morph 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG ADDED
@@ -0,0 +1 @@
1
+ v0.1.0. initial release
data/LICENSE ADDED
@@ -0,0 +1,18 @@
1
+ Copyright 2008 Rob McKinnon
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to
5
+ deal in the Software without restriction, including without limitation the
6
+ rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7
+ sell copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16
+ THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
17
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Manifest ADDED
@@ -0,0 +1,9 @@
1
+ CHANGELOG
2
+ examples/forger.rb
3
+ examples/hubbit.rb
4
+ lib/morph.rb
5
+ LICENSE
6
+ README
7
+ spec/morph_spec.rb
8
+ spec/spec.opts
9
+ Manifest
data/README ADDED
@@ -0,0 +1,155 @@
1
+ Morph allows you to emerge class definitions via calling assignment methods.
2
+ Mix with Hpricot for screen scrapping fun.
3
+
4
+ Here's example code showing Morph playing with Hpricot:
5
+
6
+ require 'hpricot'; require 'open-uri'; require 'morph'
7
+
8
+ class Hubbit
9
+ include Morph # allows class to morph
10
+
11
+ def initialize name
12
+ doc = Hpricot open("http://github.com/#{name}")
13
+
14
+ (doc/'label').collect do |node|
15
+ label = node.inner_text
16
+ value = node.next_sibling.inner_text.strip
17
+
18
+ morph(label, value) # morph magic happening here!
19
+ end
20
+ end
21
+ end
22
+
23
+ def Hubbit name; Hubbit.new name; end
24
+
25
+
26
+ The model emerges from the data. Let's start by looking up 'why':
27
+
28
+ why = Hubbit 'why'
29
+
30
+ What new methods do we have?
31
+
32
+ Hubbit.morph_methods # => ["email", "email=", "name", "name="]
33
+
34
+ Ah-ha, so we have a name attribute now:
35
+
36
+ why.name #=> "why the lucky stiff"
37
+
38
+
39
+ Let's add some of why's projects:
40
+
41
+ why.projects = %w[shoes hacketyhack camping hoodwinkd hpricot markaby
42
+ mousehole parkplace poignant sandbox]
43
+
44
+ That why's a productive fellow! Note new accessor methods have been added:
45
+
46
+ Hubbit.morph_methods # => ["email", "email=", "name", "name=",
47
+ "projects", "projects="]
48
+
49
+
50
+ Let's do some more morphing:
51
+
52
+ dhh = Hubbit 'dhh'
53
+
54
+ Do we have more methods now?
55
+
56
+ Hubbit.morph_methods # => ["blog", "blog=", "company", "company=",
57
+ "email", "email=", "location", "location="
58
+ "name", "name=", "projects", "projects="]
59
+
60
+ So, a new company method has appeared:
61
+
62
+ dhh.company #=> "37signals"
63
+
64
+
65
+ Time to print the nascent attribute definitions:
66
+
67
+ puts Hubbit.print_morph_methods
68
+
69
+ # attr_accessor :name
70
+ # attr_accessor :email
71
+ # attr_accessor :blog
72
+ # attr_accessor :company
73
+ # attr_accessor :location
74
+ # attr_accessor :projects
75
+
76
+
77
+ See examples/ directory for more example code.
78
+ See LICENSE for the terms of this software.
79
+
80
+ ,
81
+ ?7+~::+II~
82
+ ?7: ,:+7
83
+ 777IIII777? 7: :?7
84
+ =I= I: 7? ,+7
85
+ I? ,, 77 7: :I
86
+ = ?7777 77 7 7 7+, :7
87
+ 7 777777 ~77+=77 I+ I? ,7
88
+ :7 77 ~77 I I7 7 ?: ?
89
+ I 77 7, 7 7 :I I ?
90
+ 7 ?77=7~ 77777 7 ~+ ,+
91
+ 7~ 7 :I7?~ 7
92
+ =? 7 ?I ~I77= I=
93
+ 7 ? :, 7 I7777, 7 7
94
+ ? 777?~~7777+ 7 7~ 7
95
+ ?7 ,777777=, ,7 7 ,7
96
+ 7= , =7 7: 7
97
+ +7 :7 7 ,I
98
+ :7 ?~ 7? 7
99
+ 7 7 ~II7~, 7
100
+ 7 7 , =7777777?+,,, I=
101
+ :7, ~==, 7
102
+ II~,, 77~
103
+ ,I? +777
104
+ 7+, ~7777:
105
+ == :77
106
+ :7: ,7I
107
+ 7I 7
108
+ I ,7, 7
109
+ =7 77=7 7
110
+ ,7 7I 7 7
111
+ I, I7 7 7
112
+ ?, ,7 7, 7
113
+ 7 7~ 7, 7
114
+ 7 ,7I 7 7
115
+ =+ =7 7 ~=
116
+ =7 7, 7 7
117
+ ,7, ~7IIII7+, 7
118
+ +: II I
119
+ ?7 I? +~
120
+ II, +I 7
121
+ ~7 ,I 7
122
+ 7= ~7 7
123
+ ?7, ~7+ ?~
124
+ ~7777I= ,7
125
+ 7: 7
126
+ I 7
127
+ I ,:77I 7
128
+ I :7 I
129
+ I =~
130
+ 7 , ,7
131
+ +, 7 : ,7
132
+ + 7 + 7
133
+ + 7 + ,7
134
+ 7 I ? ,7
135
+ 7 +: 7 ,7
136
+ 7 =+ 7 ,7
137
+ 7 :I I ,7
138
+ 7 :I 7 7
139
+ 7 :I I 7
140
+ I, ,7 I: 7
141
+ =+ ,7 ? 7
142
+ :?, ,7 7, 7
143
+ I: ,7 7, ?
144
+ :7 ,7 7, ,
145
+ +I, : ? ,=
146
+ += ~ =~ 7
147
+ :II,, = I ?
148
+ =I= ? 7, :7
149
+ II~ I 7, ,II
150
+ 7~ ~7 7 ,=7
151
+ = =7 I, ::
152
+ 77II?==?II777777777777777 7~ 7
153
+ 77+,, 7:
154
+ 777777+:,~777
155
+
@@ -0,0 +1,31 @@
1
+ require 'hpricot'; require 'open-uri'; require 'morph'
2
+
3
+ # An example of Morph playing with Hpricot
4
+ class Forger
5
+
6
+ include Morph
7
+
8
+ def initialize name
9
+ begin
10
+ doc = Hpricot open("http://rubyforge.org/users/#{name}")
11
+
12
+ table = doc.at('td[text() = "Personal Information"]').parent.parent
13
+ values = table/'tr/td/strong'
14
+
15
+ values.collect do |node|
16
+ value = node.inner_text.strip
17
+ label = node.at('../../td[1]').inner_text
18
+ morph(label, value)
19
+ end
20
+ rescue
21
+ raise "Couldn't find forger with name: #{name}"
22
+ end
23
+ end
24
+ end
25
+
26
+ def Forger name
27
+ Forger.new name
28
+ end
29
+
30
+ #> why = Forger 'why'
31
+ #> dhh = Forger 'webster123'
@@ -0,0 +1,30 @@
1
+ require 'hpricot'; require 'open-uri'; require 'morph'
2
+
3
+ # An example of Morph playing with Hpricot
4
+ class Hubbit
5
+
6
+ include Morph
7
+
8
+ def initialize name
9
+ begin
10
+ doc = Hpricot open("http://github.com/#{name}")
11
+
12
+ (doc/'label').collect do |node|
13
+ label = node.inner_text
14
+ value = node.next_sibling.inner_text.strip
15
+
16
+ morph(label, value) # magic morphing happening here!
17
+ end
18
+ rescue
19
+ raise "Couldn't find hubbit with name: #{name}"
20
+ end
21
+ end
22
+ end
23
+
24
+ def Hubbit name
25
+ Hubbit.new name
26
+ end
27
+
28
+ # why = Hubbit 'why'
29
+ # dhh = Hubbit 'dhh'
30
+
data/lib/morph.rb ADDED
@@ -0,0 +1,82 @@
1
+ module Morph
2
+ VERSION = "0.1.0"
3
+
4
+ def self.included(base)
5
+ base.extend ClassMethods
6
+ base.send(:include, InstanceMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+
11
+ @@morph_methods = {}
12
+
13
+ def convert_to_morph_method_name label
14
+ name = label.downcase.tr('()*',' ').gsub('%','percentage').strip.chomp(':').strip.gsub(/\s/,'_').squeeze('_')
15
+ name = '_'+name if name =~ /^\d/
16
+ name
17
+ end
18
+
19
+ def morph_accessor symbol
20
+ attribute = symbol.to_s
21
+ @@morph_methods[attribute] = true
22
+ @@morph_methods[attribute+'='] = true
23
+ class_eval "attr_accessor :#{attribute}"
24
+ end
25
+
26
+ def morph_methods
27
+ @@morph_methods.keys.sort
28
+ end
29
+
30
+ def remove_method symbol
31
+ @@morph_methods.delete symbol.to_s
32
+ super
33
+ end
34
+
35
+ def remove_morph_writers
36
+ writers = morph_methods.select { |m| m =~ /=\Z/ }
37
+ writers.each do |writer|
38
+ class_eval "remove_method :#{writer}"
39
+ end
40
+ end
41
+
42
+ def print_morph_methods
43
+ methods = morph_methods
44
+ writers = methods.select { |m| m =~ /=\Z/ }
45
+ readers = methods.reject { |m| m =~ /=\Z/ }
46
+
47
+ accessors = readers.select { |m| writers.include? "#{m}=" }
48
+ readers = readers.reject { |m| accessors.include? m }
49
+ writers = writers.reject { |m| accessors.include? m.chomp('=') }
50
+
51
+ attributes = accessors.collect { |attribute| "attr_accessor :#{attribute}\n" }
52
+ attributes += readers.collect { |attribute| "attr_reader :#{attribute}\n" }
53
+ attributes += writers.collect { |attribute| "attr_writer :#{attribute}\n" }
54
+
55
+ attributes.join.chop
56
+ end
57
+ end
58
+
59
+ module InstanceMethods
60
+
61
+ def morph label, value
62
+ attribute = self.class.convert_to_morph_method_name label
63
+ send("#{attribute}=".to_sym, value)
64
+ end
65
+
66
+ def method_missing symbol, *args
67
+ attribute = symbol.to_s.chomp '='
68
+ if Object.instance_methods.include?(attribute)
69
+ raise "'#{attribute}' is an instance_method on Object, cannot create accessor methods for '#{attribute}'"
70
+ else
71
+ is_writer = symbol.to_s =~ /=\Z/
72
+ if is_writer
73
+ value = args[0]
74
+ empty_value = (value.nil? or (value.is_a?(String) && value.strip.size == 0))
75
+ return if empty_value
76
+ end
77
+ self.class.morph_accessor attribute.to_sym
78
+ send(symbol, *args)
79
+ end
80
+ end
81
+ end
82
+ end
data/morph.gemspec ADDED
@@ -0,0 +1,56 @@
1
+
2
+ # Gem::Specification for Morph-0.1.0
3
+ # Originally generated by Echoe
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = %q{morph}
7
+ s.version = "0.1.0"
8
+
9
+ s.specification_version = 2 if s.respond_to? :specification_version=
10
+
11
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
12
+ s.authors = ["Rob McKinnon"]
13
+ s.date = %q{2008-03-24}
14
+ s.description = %q{Morph allows you to emerge class definitions via calling assignment methods.}
15
+ s.email = ["rob ~@nospam@~ rubyforge.org"]
16
+ s.files = ["CHANGELOG", "examples/forger.rb", "examples/hubbit.rb", "lib/morph.rb", "LICENSE", "README", "spec/morph_spec.rb", "spec/spec.opts", "Manifest", "morph.gemspec"]
17
+ s.has_rdoc = true
18
+ s.homepage = %q{}
19
+ s.require_paths = ["lib"]
20
+ s.rubyforge_project = %q{morph}
21
+ s.rubygems_version = %q{1.0.1}
22
+ s.summary = %q{Morph allows you to emerge class definitions via calling assignment methods.}
23
+ end
24
+
25
+
26
+ # # Original Rakefile source (requires the Echoe gem):
27
+ #
28
+ # require 'rubygems'
29
+ # require 'spec'
30
+ # require 'lib/morph'
31
+ #
32
+ # begin
33
+ # require 'echoe'
34
+ #
35
+ # Echoe.new("morph", Morph::VERSION) do |morph|
36
+ # morph.author = ["Rob McKinnon"]
37
+ # morph.email = ["rob ~@nospam@~ rubyforge.org"]
38
+ # morph.description = File.readlines("README").first
39
+ # morph.rubyforge_name = "morph"
40
+ # end
41
+ #
42
+ # rescue LoadError
43
+ # puts "You need to install the echoe gem to perform meta operations on this gem"
44
+ # end
45
+ #
46
+ # desc "Open an irb session preloaded with this library"
47
+ # task :console do
48
+ # sh "irb -rubygems -r ./lib/morph.rb"
49
+ # end
50
+ #
51
+ # desc "Run spec runner"
52
+ # task(:test) do
53
+ # files = FileList['spec/**/*_spec.rb']
54
+ # Spec::Runner::CommandLine.run(rspec_options)
55
+ # system "ruby spec/spec_runner.rb #{files} --format specdoc"
56
+ # end
@@ -0,0 +1,308 @@
1
+ $KCODE = "u"
2
+
3
+ require File.dirname(__FILE__) + '/../lib/morph'
4
+
5
+ module MorphSpecHelperMethods
6
+
7
+ def initialize_morph_class
8
+ @morphed_class = eval 'class ExampleMorph; include Morph; end'
9
+ end
10
+
11
+ def initialize_morph
12
+ initialize_morph_class
13
+ @original_instance_methods = @morphed_class.instance_methods
14
+ @morph = @morphed_class.new
15
+ end
16
+
17
+ def remove_morph_methods
18
+ @morphed_class.instance_methods.each do |method|
19
+ @morphed_class.class_eval "remove_method :#{method}" unless @original_instance_methods.include?(method)
20
+ end
21
+ end
22
+
23
+ def instance_methods
24
+ @morphed_class.instance_methods
25
+ end
26
+
27
+ def morph_methods
28
+ @morphed_class.morph_methods
29
+ end
30
+
31
+ def check_convert_to_morph_method_name label, method_name
32
+ initialize_morph_class
33
+ @morphed_class.convert_to_morph_method_name(label).should == method_name
34
+ end
35
+ end
36
+
37
+ describe "class with generated accessor methods added", :shared => true do
38
+
39
+ include MorphSpecHelperMethods
40
+ before :all do initialize_morph; end
41
+ after :all do remove_morph_methods; end
42
+
43
+ it 'should add reader method to class instance_methods list' do
44
+ instance_methods.include?(@attribute).should == true
45
+ end
46
+
47
+ it 'should add writer method to class instance_methods list' do
48
+ instance_methods.include?("#{@attribute}=").should == true
49
+ end
50
+
51
+ it 'should add reader method to class morph_methods list' do
52
+ morph_methods.include?(@attribute).should == true
53
+ end
54
+
55
+ it 'should add writer method to class morph_methods list' do
56
+ morph_methods.include?("#{@attribute}=").should == true
57
+ end
58
+
59
+ it 'should only have generated accessor methods in morph_methods list' do
60
+ morph_methods.size.should == @expected_morph_methods_count
61
+ end
62
+
63
+ it 'should be able to print morph method declarations' do
64
+ @morphed_class.print_morph_methods.should == %Q|attr_accessor :#{@attribute}|
65
+ end
66
+ end
67
+
68
+ describe "class without generated accessor methods added", :shared => true do
69
+ include MorphSpecHelperMethods
70
+
71
+ before :all do
72
+ initialize_morph
73
+ end
74
+
75
+ after :all do
76
+ remove_morph_methods
77
+ end
78
+
79
+ it 'should not add reader method to class instance_methods list' do
80
+ instance_methods.include?(@attribute).should == false
81
+ end
82
+
83
+ it 'should not add writer method to class instance_methods list' do
84
+ instance_methods.include?("#{@attribute}=").should == false
85
+ end
86
+
87
+ it 'should not add reader method to class morph_methods list' do
88
+ morph_methods.include?(@attribute).should == false
89
+ end
90
+
91
+ it 'should not add writer method to class morph_methods list' do
92
+ morph_methods.include?("#{@attribute}=").should == false
93
+ end
94
+
95
+ it 'should have empty morph_methods list' do
96
+ morph_methods.size.should == 0
97
+ end
98
+ end
99
+
100
+ describe Morph, "when reader method that didn't exist before is called" do
101
+ before :each do
102
+ remove_morph_methods
103
+ @morph.noise
104
+ @attribute = 'noise'
105
+ @expected_morph_methods_count = 2
106
+ end
107
+
108
+ it_should_behave_like "class with generated accessor methods added"
109
+
110
+ it 'should return nil if reader is called' do
111
+ @morph.noise.should == nil
112
+ end
113
+ end
114
+
115
+ describe Morph, "when writer method that didn't exist before is called with non-nil value" do
116
+ before :each do
117
+ remove_morph_methods
118
+ @quack = 'quack'
119
+ @morph.noise= @quack
120
+ @attribute = 'noise'
121
+ @expected_morph_methods_count = 2
122
+ end
123
+
124
+ it_should_behave_like "class with generated accessor methods added"
125
+
126
+ it 'should return assigned value when reader method called' do
127
+ @morph.noise.should == @quack
128
+ end
129
+ end
130
+
131
+ describe Morph, "when writer method that didn't exist before is in unicode" do
132
+ before :each do
133
+ remove_morph_methods
134
+ @age = 19
135
+ @attribute = "年龄"
136
+ @morph.morph(@attribute, @age)
137
+ @expected_morph_methods_count = 2
138
+ end
139
+
140
+ it_should_behave_like "class with generated accessor methods added"
141
+
142
+ it 'should return assigned value when reader method called' do
143
+ @morph.send(@attribute.to_sym) == @age
144
+ end
145
+ end
146
+
147
+ describe Morph, "when writer method that didn't exist before is called with nil value" do
148
+ before :each do
149
+ remove_morph_methods
150
+ @morph.morph('Pizza', nil)
151
+ @attribute = 'pizza'
152
+ end
153
+
154
+ it_should_behave_like "class without generated accessor methods added"
155
+ end
156
+
157
+ describe Morph, 'when morph method used to set blank space attribute value' do
158
+ before :each do
159
+ remove_morph_methods
160
+ @morph.morph('Pizza', ' ')
161
+ @attribute = 'pizza'
162
+ end
163
+
164
+ it_should_behave_like "class without generated accessor methods added"
165
+ end
166
+
167
+ describe Morph, 'when morph method used to set nil attribute value' do
168
+ before :each do
169
+ remove_morph_methods
170
+ @morph.morph('Pizza', nil)
171
+ @attribute = 'pizza'
172
+ end
173
+
174
+ it_should_behave_like "class without generated accessor methods added"
175
+ end
176
+
177
+
178
+ describe Morph, 'when remove_morph_writers is called after a generated method has been added' do
179
+
180
+ include MorphSpecHelperMethods
181
+ before :all do initialize_morph; end
182
+ after :all do remove_morph_methods; end
183
+
184
+ before :each do
185
+ remove_morph_methods
186
+ @morph.noise= 'quack'
187
+ @attribute = 'noise'
188
+ @morphed_class.remove_morph_writers
189
+ end
190
+
191
+ it 'should remove a morph generated writer method from morph_methods list' do
192
+ morph_methods.include?('noise=').should == false
193
+ morph_methods.size.should == 1
194
+ end
195
+
196
+ it 'should remove a morph generated writer method from class instance_methods list' do
197
+ instance_methods.include?('noise=').should == false
198
+ end
199
+
200
+ it 'should be able to print morph method declarations' do
201
+ @morphed_class.print_morph_methods.should == %Q|attr_reader :#{@attribute}|
202
+ end
203
+
204
+ end
205
+
206
+ describe Morph, "when reader method called is a class method" do
207
+
208
+ before :each do
209
+ remove_morph_methods
210
+ @morph.name
211
+ @attribute = 'name'
212
+ @expected_morph_methods_count = 2
213
+ end
214
+
215
+ it_should_behave_like "class with generated accessor methods added"
216
+ end
217
+
218
+ describe Morph, "when writer method called is a class method" do
219
+
220
+ before :each do
221
+ remove_morph_methods
222
+ @value = 'Morph'
223
+ @morph.name = @value
224
+ @attribute = 'name'
225
+ @expected_morph_methods_count = 2
226
+ end
227
+
228
+ it_should_behave_like "class with generated accessor methods added"
229
+
230
+ it 'should return assigned value when reader method called' do
231
+ @morph.name.should == @value
232
+ end
233
+ end
234
+
235
+ describe Morph, "when class= is called" do
236
+
237
+ include MorphSpecHelperMethods
238
+ before :all do initialize_morph; end
239
+ after :all do remove_morph_methods; end
240
+
241
+ it 'should throw exception if non nil object is passed' do
242
+ lambda { @morph.class = 'Red' }.should raise_error(/cannot create accessor methods/)
243
+ end
244
+
245
+ it 'should throw exception if nil object is passed' do
246
+ lambda { @morph.class = nil }.should raise_error(/cannot create accessor methods/)
247
+ end
248
+ end
249
+
250
+ describe Morph, "when converting label text to morph method name" do
251
+
252
+ include MorphSpecHelperMethods
253
+
254
+ it 'should upper case to lower case' do
255
+ check_convert_to_morph_method_name 'CaSe', 'case'
256
+ end
257
+ it 'should convert single space to underscorce' do
258
+ check_convert_to_morph_method_name 'First reading', 'first_reading'
259
+ end
260
+ it 'should convert multiple spaces to single underscorce' do
261
+ check_convert_to_morph_method_name "First reading", 'first_reading'
262
+ end
263
+ it 'should convert tabs to single underscorce' do
264
+ check_convert_to_morph_method_name "First\t\treading", 'first_reading'
265
+ end
266
+ it 'should convert new line chars to single underscorce' do
267
+ check_convert_to_morph_method_name "First\r\nreading", 'first_reading'
268
+ end
269
+ it 'should remove leading and trailing whitespace new line chars to single underscorce' do
270
+ check_convert_to_morph_method_name " \t\r\nFirst reading \t\r\n", 'first_reading'
271
+ end
272
+ it 'should remove trailing colon surrounded by whitespace' do
273
+ check_convert_to_morph_method_name "First reading : ", 'first_reading'
274
+ end
275
+ it 'should remove parenthesis' do
276
+ check_convert_to_morph_method_name 'Nav(GBX)', 'nav_gbx'
277
+ end
278
+ it 'should remove *' do
279
+ check_convert_to_morph_method_name 'Change**', 'change'
280
+ end
281
+ it 'should convert % character to the text "percentage"' do
282
+ check_convert_to_morph_method_name '% Change', 'percentage_change'
283
+ end
284
+ it 'should precede leading digit with an underscore character' do
285
+ check_convert_to_morph_method_name '52w_high', '_52w_high'
286
+ end
287
+ it 'should handle unicode name' do
288
+ check_convert_to_morph_method_name '年龄', '年龄'
289
+ end
290
+ end
291
+
292
+ describe Morph, 'when morph method used to set attribute value and attribute name ends with colon' do
293
+
294
+ before :each do
295
+ remove_morph_methods
296
+ @value = '20 Mar 2008'
297
+ @morph.morph('First reading : ', @value)
298
+ @attribute = 'first_reading'
299
+ @expected_morph_methods_count = 2
300
+ end
301
+
302
+ it_should_behave_like "class with generated accessor methods added"
303
+
304
+ it 'should return assigned value when reader method called' do
305
+ @morph.first_reading.should == @value
306
+ end
307
+ end
308
+
data/spec/spec.opts ADDED
@@ -0,0 +1,7 @@
1
+ --colour
2
+ --format
3
+ progress
4
+ --loadby
5
+ mtime
6
+ --reverse
7
+ --backtrace
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: morph
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Rob McKinnon
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2008-03-24 00:00:00 +00:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Morph allows you to emerge class definitions via calling assignment methods.
17
+ email:
18
+ - rob ~@nospam@~ rubyforge.org
19
+ executables: []
20
+
21
+ extensions: []
22
+
23
+ extra_rdoc_files: []
24
+
25
+ files:
26
+ - CHANGELOG
27
+ - examples/forger.rb
28
+ - examples/hubbit.rb
29
+ - lib/morph.rb
30
+ - LICENSE
31
+ - README
32
+ - spec/morph_spec.rb
33
+ - spec/spec.opts
34
+ - Manifest
35
+ - morph.gemspec
36
+ has_rdoc: true
37
+ homepage: ""
38
+ post_install_message:
39
+ rdoc_options: []
40
+
41
+ require_paths:
42
+ - lib
43
+ required_ruby_version: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: "0"
48
+ version:
49
+ required_rubygems_version: !ruby/object:Gem::Requirement
50
+ requirements:
51
+ - - ">="
52
+ - !ruby/object:Gem::Version
53
+ version: "0"
54
+ version:
55
+ requirements: []
56
+
57
+ rubyforge_project: morph
58
+ rubygems_version: 1.0.1
59
+ signing_key:
60
+ specification_version: 2
61
+ summary: Morph allows you to emerge class definitions via calling assignment methods.
62
+ test_files: []
63
+