at 0.1.4 → 0.2.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.
@@ -0,0 +1,3 @@
1
+ pkg/
2
+ doc/
3
+ .yardoc/
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm use --create 1.9.3@at
@@ -1,13 +1,15 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- at (0.1.3)
5
- version (~> 1.0.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.0.0)
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.2)
68
+ redcarpet (~> 2.2)
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2010-2012 Ryan Scott Lewis <ryan@rynet.us>
1
+ Copyright (c) 2012-2013 Ryan Scott Lewis <ryan@rynet.us>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -1,44 +1,118 @@
1
1
  # At
2
2
 
3
- `At` is a small library that allows you to access instance variables on an object as
4
- if they were `attr_accessor`s for testing purposes.
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 = object.instance_eval { @instance_variable }
10
- object.instance_eval { @instance_variable = "#{value}!" }
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 = object.at.instance_variable
17
- object.at.instance_variable = "#{value}!"
26
+ value = user.at.name
27
+ user.at.name = "#{value}!"
18
28
  ```
19
29
 
20
- ## Install
30
+ ### Use Case
21
31
 
22
- ### Bundler: `gem 'at'`
32
+ `lib/user.rb`
23
33
 
24
- ### RubyGems: `gem install at`
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
- ## Usage
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
- If I want to test the output of the `full_name` method in my `User` class
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
- `At` solves these problems.
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
- require 'at'
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
- describe User, '#full_name' do
52
- it 'should output the full name correctly' do
53
- subject.at.first_name = 'John'
54
- subject.at.last_name = 'Doe'
55
-
56
- subject.full_name.should == 'John Doe'
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
- Check out the specs for a better usage example.
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.4
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.1.4"
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 = "2012-12-11"
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 = [".yardoc/object_types", ".yardoc/objects/root.dat", ".yardoc/proxy_types", "Gemfile", "Gemfile.lock", "Guardfile", "LICENSE", "README.md", "Rakefile", "VERSION", "at.gemspec", "lib/at.rb", "lib/at/import.rb", "spec/at_spec.rb", "spec/spec_helper.rb"]
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
- class MethodToInstanceVariableProxy
8
-
9
- def initialize(parent)
10
- @parent = parent
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
- def at
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
@@ -0,0 +1,6 @@
1
+ require 'at'
2
+
3
+ # Here, we include At to the Object class.
4
+ class Object
5
+ include At
6
+ end
@@ -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
@@ -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.1.4
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: 2012-12-11 00:00:00.000000000 Z
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
- - .yardoc/object_types
149
- - .yardoc/objects/root.dat
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/import.rb
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:
Binary file
Binary file
Binary file
@@ -1,10 +0,0 @@
1
- require 'pathname'
2
-
3
- __LIB__ ||= Pathname.new(__FILE__).join('..', '..').expand_path
4
- $:.unshift(__LIB__.to_s) unless $:.include?(__LIB__.to_s)
5
-
6
- require 'at'
7
-
8
- class Object
9
- include At
10
- end