sub-setter 0.0.2

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,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: []