sub-setter 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sub-setter.gemspec
4
+ gemspec
@@ -0,0 +1,37 @@
1
+ SubSetter Pattern implementation for Ruby
2
+ =========================================
3
+
4
+ As described in [SubSetter Pattern for Ruby][xaviervia-subsetter].
5
+
6
+ Installation
7
+ ------------
8
+
9
+ > Not yet
10
+
11
+ This implementation creates
12
+ ---------------------------
13
+
14
+ - The **SubSetter** Module, containing three methods (and three more aliases) that are included into Object.
15
+ - The **SubSetter::Object** Class, implementation (empty right now) of a generic subsetter for Object.
16
+
17
+ [xaviervia-subsetter]: http://xaviervia.com.ar/patterns/sub-setter
18
+
19
+ New methods in Object
20
+ ---------------------
21
+
22
+ ### Public
23
+
24
+ - `subsetter`: returns an instance of the designated subsetter for the class of this instance.
25
+ - `_subsetter`, `by` and `filter`: aliases for `subsetter`. `by` and `filter` are added for legibility, and `_subsetter` in the remote case that all other method names are overriden, in order to not jeopardize the subsetting functionality
26
+
27
+ > `_subsetter` is the recommended form to be used when developing a library on top of the sub-setter gem.
28
+
29
+ ### Private
30
+
31
+ - `_subsetter_for(Class)`: returns an instance of the designated subsetting class for the given `Class`
32
+ - `_has_subsetter_for(Class)`: returns true if for the passed class a corresponding subsetter class exists, false otherwise
33
+
34
+ License
35
+ -------
36
+
37
+ GPL
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,3 @@
1
+ require "sub-setter/version"
2
+ require "sub-setter/sub-setter"
3
+ require "sub-setter/object"
@@ -0,0 +1,3 @@
1
+ class Object
2
+ include SubSetter
3
+ end
@@ -0,0 +1,71 @@
1
+ # SubSetter Pattern implementation for Ruby
2
+ #
3
+ # As described in SubSetter Pattern for Ruby
4
+ # http://xaviervia.com.ar/patterns/sub-setter
5
+ module SubSetter
6
+ # Gets the subsetter for self
7
+ #
8
+ # The default behaviour is, for class Klass, to look for a
9
+ # class named SubSetter::Klass; for a class Library::Klass, a class
10
+ # named SubSetter::Library::Klass, following the criteria described
11
+ # in http://xaviervia.com.ar/patterns/sub-setter
12
+ #
13
+ # If a SubSetter for the current class is not found, a SubSetter for
14
+ # the superclass is searched instead, and if is not found in that
15
+ # class, further in the class hierarchy until a SubSetter is found.
16
+ def subsetter
17
+ _subsetter_for(self.class).new self
18
+ end
19
+
20
+ alias :by :subsetter
21
+ alias :filter :subsetter
22
+ alias :_subsetter :subsetter
23
+
24
+ private
25
+ # Returns an instance of the designated subsetting class for the
26
+ # given `Class`
27
+ def _subsetter_for the_class
28
+ if RUBY_VERSION.match /1.9/
29
+ Kernel.raise RuntimeError, "You are awesome. Why on Earth do you want to subset a Basi... Anyway, you rule. Seriously.\nFWI, this is an error, you can't do that. Stop trying. Cheers, xav" if the_class == BasicObject
30
+ end
31
+ return eval("SubSetter::#{the_class.name}") if _there_is_subsetter_for? the_class
32
+ _subsetter_for the_class.superclass
33
+ end
34
+
35
+ # Returns true if for the passed class a corresponding subsetter
36
+ # class exists, false otherwise
37
+ def _there_is_subsetter_for? the_class
38
+ unless RUBY_VERSION.match /1.8/
39
+ return ::SubSetter.const_defined? the_class.name, false unless the_class.name["::"]
40
+
41
+ parts = the_class.name.split("::")
42
+ class_name = parts.pop
43
+ current_module = ::SubSetter
44
+ while parts.length > 0
45
+ return false unless current_module.const_defined? parts.first, false
46
+ current_module = current_module.const_get parts.shift, false
47
+ end
48
+ current_module.const_defined? class_name, false
49
+ else
50
+ return ::SubSetter.const_defined? the_class.name unless the_class.name["::"]
51
+
52
+ parts = the_class.name.split("::")
53
+ class_name = parts.pop
54
+ current_module = ::SubSetter
55
+ while parts.length > 0
56
+ return false unless current_module.const_defined? parts.first
57
+ current_module = current_module.const_get parts.shift
58
+ end
59
+ current_module.const_defined? class_name
60
+ end
61
+ end
62
+
63
+ public
64
+
65
+ # SubSetter for Object: placeholder mostly
66
+ class Object
67
+ def initialize instance
68
+ @source = instance
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,5 @@
1
+ module Sub
2
+ module Setter
3
+ VERSION = "0.0.2"
4
+ end
5
+ end
@@ -0,0 +1,7 @@
1
+ require "sub-setter/object"
2
+
3
+ describe Object do
4
+ it "should include SubSetter in its ancestors" do
5
+ Object.ancestors.should include SubSetter
6
+ end
7
+ end
@@ -0,0 +1,213 @@
1
+ require "sub-setter/sub-setter"
2
+
3
+ describe SubSetter do
4
+ shared_examples_for "any subsetting" do
5
+ it "should call _subsetter_for with the class as argument" do
6
+ the_object = Object.new
7
+ the_object.extend SubSetter
8
+ the_object.should_receive(:_subsetter_for).with(Object).and_return(SubSetter::Object)
9
+ the_object.send @method
10
+ end
11
+
12
+ it "should call .new on the returned class" do
13
+ the_object = Object.new
14
+ the_object.extend SubSetter
15
+ SubSetter::Object.should_receive(:new).with(the_object)
16
+ the_object.send @method
17
+ end
18
+
19
+ it "should return an instance of the designated subsetter" do
20
+ the_object = Object.new
21
+ the_object.extend SubSetter
22
+ the_object.send(@method).should be_instance_of SubSetter::Object
23
+ end
24
+ end
25
+
26
+ describe "#_subsetter" do
27
+ before { @method = :_subsetter }
28
+ it_behaves_like "any subsetting"
29
+ end
30
+
31
+ describe "#subsetter" do
32
+ before { @method = :subsetter }
33
+ it_behaves_like "any subsetting"
34
+ end
35
+
36
+ describe "#filter" do
37
+ before { @method = :filter }
38
+ it_behaves_like "any subsetting"
39
+ end
40
+
41
+ describe "#by" do
42
+ before { @method = :by }
43
+ it_behaves_like "any subsetting"
44
+ end
45
+
46
+ # Priv8 methods
47
+ describe "#_there_is_subsetter_for?" do
48
+ context "there it no subsetter for this class" do
49
+ it "should return false" do
50
+ class Klass
51
+ include SubSetter
52
+ def test_me
53
+ _there_is_subsetter_for? self.class
54
+ end
55
+ end
56
+
57
+ Klass.new.test_me.should === false
58
+ end
59
+ end
60
+
61
+ context "there is a subsetter for this class" do
62
+ it "should return true" do
63
+ module SubSetter; class Klass; end; end
64
+ class Klass
65
+ include SubSetter
66
+ def test_me
67
+ _there_is_subsetter_for? self.class
68
+ end
69
+ end
70
+
71
+ Klass.new.test_me.should === true
72
+ end
73
+ end
74
+ end
75
+
76
+ describe "#_subsetter_for" do
77
+ context "this is an Object" do
78
+ it "should return SubSetter::Object" do
79
+ the_object = Object.new
80
+ the_object.extend SubSetter
81
+ class << the_object
82
+ def test_me
83
+ _subsetter_for self.class
84
+ end
85
+ end
86
+
87
+ the_object.test_me.should == SubSetter::Object
88
+ end
89
+ end
90
+
91
+ if RUBY_VERSION.match /1.9/
92
+ context "this is a BasicObject" do
93
+ it "should raise an awesome exception" do
94
+ ay = BasicObject.new
95
+ class BasicObject
96
+ include ::SubSetter
97
+ end
98
+
99
+ def ay.genius
100
+ _subsetter_for BasicObject
101
+ end
102
+
103
+ expect { ay.genius
104
+ }.to raise_error RuntimeError, "You are awesome. Why on Earth do you want to subset a Basi... Anyway, you rule. Seriously.\nFWI, this is an error, you can't do that. Stop trying. Cheers, xav"
105
+ end
106
+ end
107
+ end
108
+
109
+ context "there is a subsetter for the superclass" do
110
+ it "should return the superclass's subsetter" do
111
+ class SuperKlass; end
112
+ class ActualKlass < SuperKlass; end
113
+
114
+ module SubSetter; class SuperKlass; end; end
115
+
116
+ klassy = ActualKlass.new
117
+ klassy.extend SubSetter
118
+
119
+ def klassy.test_me
120
+ _subsetter_for self.class
121
+ end
122
+
123
+ klassy.test_me.should == SubSetter::SuperKlass
124
+ end
125
+ end
126
+
127
+ context "there is a subsetter for the supersuperclass" do
128
+ it "should return the supersuperclass's subsetter" do
129
+ class CoolKlass; end
130
+ class IMRunningOutOfNamesKlass < CoolKlass; end
131
+ class WhyWasThatLong < IMRunningOutOfNamesKlass; end
132
+
133
+ module SubSetter; class CoolKlass; end; end
134
+
135
+ klick = WhyWasThatLong.new
136
+ klick.extend SubSetter
137
+
138
+ def klick.test_me; _subsetter_for self.class; end
139
+
140
+ klick.test_me.should == SubSetter::CoolKlass
141
+ end
142
+ end
143
+
144
+ context "has two superclasses but non of them has a subsetter" do
145
+ it "should return SubSetter::Object" do
146
+ class SuperSuper; end
147
+ class Superr < SuperSuper; end
148
+ class Aktual < Superr; end
149
+
150
+ kla = Aktual.new
151
+ kla.extend SubSetter
152
+ def kla.test; _subsetter_for self.class; end
153
+
154
+ kla.test.should == SubSetter::Object
155
+ end
156
+ end
157
+
158
+ context "there is a subsetter for this class" do
159
+ it "should return that subsetter" do
160
+ class Hey; end
161
+ module SubSetter; class Hey; end; end
162
+
163
+ hi = Hey.new
164
+ hi.extend SubSetter
165
+ def hi.t; _subsetter_for self.class; end
166
+
167
+ hi.t.should == SubSetter::Hey
168
+ end
169
+ end
170
+
171
+ context "this class is within several modules" do
172
+ context "there is a subsetter for this class" do
173
+ it "should return that subsetter" do
174
+ module One; module Two; module Three; class AAA;
175
+ end; end; end; end
176
+
177
+ module SubSetter; module One; module Two; module Three;
178
+ class AAA;
179
+ end; end; end; end; end
180
+
181
+ deeeep = One::Two::Three::AAA.new
182
+ deeeep.extend SubSetter
183
+
184
+ def deeeep.dowwwn; _subsetter_for self.class; end
185
+
186
+ deeeep.dowwwn.should == SubSetter::One::Two::Three::AAA
187
+ end
188
+ end
189
+ end
190
+ end
191
+ end
192
+
193
+ describe SubSetter::Object do
194
+ describe "#new" do
195
+ it "should require an argument" do
196
+ SubSetter::Object.new "an argument"
197
+ end
198
+
199
+ it "should store the argument in the @source variable" do
200
+ module SubSetter
201
+ class Object
202
+ def reveal_source
203
+ @source
204
+ end
205
+ end
206
+ end
207
+
208
+ the_var = %w{1 2 3 4}
209
+ subsetter_the_var = SubSetter::Object.new the_var
210
+ subsetter_the_var.reveal_source.should === the_var
211
+ end
212
+ end
213
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sub-setter/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sub-setter"
7
+ s.version = Sub::Setter::VERSION
8
+ s.authors = ["Xavier Via"]
9
+ s.email = ["xavierviacanel@gmail.com"]
10
+ s.homepage = "http://xaviervia.com.ar/patterns/sub-setter"
11
+ s.summary = %q{SubSetter Design Pattern implementation for Ruby}
12
+ s.description = %q{SubSetter Design Pattern implementation for Ruby}
13
+
14
+ s.rubyforge_project = "sub-setter"
15
+
16
+ s.add_development_dependency "rspec"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
+ s.require_paths = ["lib"]
22
+
23
+ # specify any dependencies here; for example:
24
+ # s.add_development_dependency "rspec"
25
+ # s.add_runtime_dependency "rest-client"
26
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sub-setter
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Xavier Via
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-04-06 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70621040 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70621040
25
+ description: SubSetter Design Pattern implementation for Ruby
26
+ email:
27
+ - xavierviacanel@gmail.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - Gemfile
34
+ - README.md
35
+ - Rakefile
36
+ - lib/sub-setter.rb
37
+ - lib/sub-setter/object.rb
38
+ - lib/sub-setter/sub-setter.rb
39
+ - lib/sub-setter/version.rb
40
+ - spec/sub-setter/object_spec.rb
41
+ - spec/sub-setter/sub-setter_spec.rb
42
+ - sub-setter.gemspec
43
+ homepage: http://xaviervia.com.ar/patterns/sub-setter
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project: sub-setter
63
+ rubygems_version: 1.8.15
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: SubSetter Design Pattern implementation for Ruby
67
+ test_files: []