morph 0.1.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.
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
+