morph 0.2.0 → 0.2.1
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 +4 -0
- data/Manifest +1 -0
- data/Rakefile +24 -0
- data/lib/morph.rb +18 -20
- data/morph.gemspec +76 -46
- data/spec/morph_spec.rb +266 -243
- data/spec/morph_spec_helper.rb +122 -0
- metadata +18 -7
data/CHANGELOG
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
v0.2.1. better accomodation of unicode method names
|
2
|
+
|
3
|
+
v0.2.0. added script_generate method; fixed bug occurring when two morph classes exist
|
4
|
+
|
1
5
|
v0.1.5. added morph_attributes instance method
|
2
6
|
|
3
7
|
v0.1.4. can now pass code block to customize the dynamically added methods
|
data/Manifest
CHANGED
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'spec'
|
3
|
+
require 'lib/morph'
|
4
|
+
|
5
|
+
begin
|
6
|
+
require 'echoe'
|
7
|
+
|
8
|
+
Echoe.new("morph", Morph::VERSION) do |m|
|
9
|
+
m.author = ["Rob McKinnon"]
|
10
|
+
m.email = ["rob ~@nospam@~ rubyforge.org"]
|
11
|
+
m.description = File.readlines("README").first
|
12
|
+
m.rubyforge_name = "morph"
|
13
|
+
m.rdoc_options << '--inline-source'
|
14
|
+
m.rdoc_pattern = ["README", "CHANGELOG", "LICENSE"]
|
15
|
+
end
|
16
|
+
|
17
|
+
rescue LoadError
|
18
|
+
puts "You need to install the echoe gem to perform meta operations on this gem"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Open an irb session preloaded with this library"
|
22
|
+
task :console do
|
23
|
+
sh "irb -rubygems -r ./lib/morph.rb"
|
24
|
+
end
|
data/lib/morph.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Morph
|
2
|
-
VERSION = "0.2.
|
2
|
+
VERSION = "0.2.1"
|
3
3
|
|
4
4
|
def self.included(base)
|
5
5
|
base.extend ClassMethods
|
@@ -111,26 +111,25 @@ module Morph
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
send(symbol, *args)
|
130
|
-
end
|
131
|
-
base.adding_morph_method = false
|
114
|
+
def morph_method_missing symbol, *args
|
115
|
+
attribute = symbol.to_s.chomp '='
|
116
|
+
|
117
|
+
if Object.instance_methods.include?(attribute)
|
118
|
+
raise "'#{attribute}' is an instance_method on Object, cannot create accessor methods for '#{attribute}'"
|
119
|
+
elsif argument_provided? args
|
120
|
+
base = self.class
|
121
|
+
base.adding_morph_method = true
|
122
|
+
|
123
|
+
if block_given?
|
124
|
+
yield base, attribute
|
125
|
+
else
|
126
|
+
# base.class_eval "attr_accessor :#{attribute}"
|
127
|
+
base.class_eval "def #{attribute}; @#{attribute}; end; def #{attribute}=(value); @#{attribute} = value; end"
|
128
|
+
send(symbol, *args)
|
132
129
|
end
|
130
|
+
base.adding_morph_method = false
|
133
131
|
end
|
132
|
+
end
|
134
133
|
|
135
134
|
private
|
136
135
|
|
@@ -143,6 +142,5 @@ module Morph
|
|
143
142
|
name = '_'+name if name =~ /^\d/
|
144
143
|
name
|
145
144
|
end
|
146
|
-
|
147
145
|
end
|
148
146
|
end
|
data/morph.gemspec
CHANGED
@@ -1,53 +1,83 @@
|
|
1
1
|
|
2
|
-
# Gem::Specification for Morph-0.2.
|
2
|
+
# Gem::Specification for Morph-0.2.1
|
3
3
|
# Originally generated by Echoe
|
4
4
|
|
5
|
-
Gem::Specification
|
6
|
-
|
7
|
-
|
5
|
+
--- !ruby/object:Gem::Specification
|
6
|
+
name: morph
|
7
|
+
version: !ruby/object:Gem::Version
|
8
|
+
version: 0.2.1
|
9
|
+
platform: ruby
|
10
|
+
authors:
|
11
|
+
- Rob McKinnon
|
12
|
+
autorequire:
|
13
|
+
bindir: bin
|
8
14
|
|
9
|
-
|
15
|
+
date: 2008-08-05 00:00:00 +01:00
|
16
|
+
default_executable:
|
17
|
+
dependencies:
|
18
|
+
- !ruby/object:Gem::Dependency
|
19
|
+
name: echoe
|
20
|
+
type: :development
|
21
|
+
version_requirement:
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: "0"
|
27
|
+
version:
|
28
|
+
description: Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.
|
29
|
+
email:
|
30
|
+
- rob ~@nospam@~ rubyforge.org
|
31
|
+
executables: []
|
10
32
|
|
11
|
-
|
12
|
-
s.authors = ["Rob McKinnon"]
|
13
|
-
s.date = %q{2008-05-01}
|
14
|
-
s.description = %q{Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.}
|
15
|
-
s.email = ["rob ~@nospam@~ rubyforge.org"]
|
16
|
-
s.extra_rdoc_files = ["CHANGELOG", "LICENSE", "README"]
|
17
|
-
s.files = ["CHANGELOG", "examples/forger.rb", "examples/hubbit.rb", "lib/morph.rb", "LICENSE", "README", "spec/morph_spec.rb", "spec/spec.opts", "Manifest", "morph.gemspec"]
|
18
|
-
s.has_rdoc = true
|
19
|
-
s.homepage = %q{}
|
20
|
-
s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Morph", "--main", "README", "--inline-source"]
|
21
|
-
s.require_paths = ["lib"]
|
22
|
-
s.rubyforge_project = %q{morph}
|
23
|
-
s.rubygems_version = %q{1.1.0}
|
24
|
-
s.summary = %q{Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.}
|
25
|
-
end
|
33
|
+
extensions: []
|
26
34
|
|
35
|
+
extra_rdoc_files:
|
36
|
+
- CHANGELOG
|
37
|
+
- LICENSE
|
38
|
+
- README
|
39
|
+
files:
|
40
|
+
- CHANGELOG
|
41
|
+
- examples/forger.rb
|
42
|
+
- examples/hubbit.rb
|
43
|
+
- lib/morph.rb
|
44
|
+
- LICENSE
|
45
|
+
- README
|
46
|
+
- spec/morph_spec.rb
|
47
|
+
- spec/morph_spec_helper.rb
|
48
|
+
- spec/spec.opts
|
49
|
+
- Manifest
|
50
|
+
- morph.gemspec
|
51
|
+
- Rakefile
|
52
|
+
has_rdoc: true
|
53
|
+
homepage: ""
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options:
|
56
|
+
- --line-numbers
|
57
|
+
- --inline-source
|
58
|
+
- --title
|
59
|
+
- Morph
|
60
|
+
- --main
|
61
|
+
- README
|
62
|
+
- --inline-source
|
63
|
+
require_paths:
|
64
|
+
- lib
|
65
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: "0"
|
70
|
+
version:
|
71
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: "1.2"
|
76
|
+
version:
|
77
|
+
requirements: []
|
27
78
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
#
|
34
|
-
# begin
|
35
|
-
# require 'echoe'
|
36
|
-
#
|
37
|
-
# Echoe.new("morph", Morph::VERSION) do |m|
|
38
|
-
# m.author = ["Rob McKinnon"]
|
39
|
-
# m.email = ["rob ~@nospam@~ rubyforge.org"]
|
40
|
-
# m.description = File.readlines("README").first
|
41
|
-
# m.rubyforge_name = "morph"
|
42
|
-
# m.rdoc_options << '--inline-source'
|
43
|
-
# m.rdoc_pattern = ["README", "CHANGELOG", "LICENSE"]
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# rescue LoadError
|
47
|
-
# puts "You need to install the echoe gem to perform meta operations on this gem"
|
48
|
-
# end
|
49
|
-
#
|
50
|
-
# desc "Open an irb session preloaded with this library"
|
51
|
-
# task :console do
|
52
|
-
# sh "irb -rubygems -r ./lib/morph.rb"
|
53
|
-
# end
|
79
|
+
rubyforge_project: morph
|
80
|
+
rubygems_version: 1.2.0
|
81
|
+
specification_version: 2
|
82
|
+
summary: Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.
|
83
|
+
test_files: []
|
data/spec/morph_spec.rb
CHANGED
@@ -1,330 +1,353 @@
|
|
1
1
|
require File.dirname(__FILE__) + '/../lib/morph'
|
2
2
|
require File.dirname(__FILE__) + '/morph_spec_helper'
|
3
3
|
|
4
|
-
describe Morph
|
5
|
-
before
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
describe Morph do
|
5
|
+
describe "when writer method that didn't exist before is called with non-nil value" do
|
6
|
+
before :each do
|
7
|
+
remove_morph_methods
|
8
|
+
@quack = 'quack'
|
9
|
+
@morph.noise= @quack
|
10
|
+
@attribute = 'noise'
|
11
|
+
@expected_morph_methods_count = 2
|
12
|
+
end
|
12
13
|
|
13
|
-
|
14
|
+
it_should_behave_like "class with generated accessor methods added"
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
16
|
+
it 'should return assigned value when reader method called' do
|
17
|
+
@morph.noise.should == @quack
|
18
|
+
end
|
18
19
|
|
19
|
-
|
20
|
-
|
21
|
-
|
20
|
+
it 'should return hash of attributes when morph_attributes called' do
|
21
|
+
@morph.morph_attributes.should == {@attribute.to_sym => @quack}
|
22
|
+
end
|
22
23
|
|
23
|
-
|
24
|
-
|
25
|
-
|
24
|
+
it 'should generate rails model generator script line, with given model name' do
|
25
|
+
@morphed_class.script_generate {|model_name| 'SomethingDifferent'}.should == "ruby script/destroy rspec_model SomethingDifferent; ruby script/generate rspec_model SomethingDifferent noise:string"
|
26
|
+
end
|
26
27
|
|
27
|
-
|
28
|
-
|
29
|
-
|
28
|
+
it 'should generate rails model generator script line' do
|
29
|
+
@morphed_class.script_generate.should == "ruby script/destroy rspec_model ExampleMorph; ruby script/generate rspec_model ExampleMorph noise:string"
|
30
|
+
end
|
30
31
|
|
31
|
-
|
32
|
-
|
32
|
+
it 'should generate rails model generator script line' do
|
33
|
+
@morphed_class.script_generate(:generator=>'model').should == "ruby script/destroy model ExampleMorph; ruby script/generate model ExampleMorph noise:string"
|
34
|
+
end
|
33
35
|
end
|
34
|
-
end
|
35
36
|
|
36
|
-
describe
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
37
|
+
describe "when writer method that didn't exist before is called with nil value" do
|
38
|
+
before :each do
|
39
|
+
remove_morph_methods
|
40
|
+
@morph.noise= nil
|
41
|
+
@attribute = 'noise'
|
42
|
+
end
|
43
|
+
|
44
|
+
it_should_behave_like "class without generated accessor methods added"
|
41
45
|
end
|
42
46
|
|
43
|
-
|
44
|
-
|
47
|
+
describe "when different writer method called on two different morph classes" do
|
48
|
+
include MorphSpecHelperMethods
|
45
49
|
|
46
|
-
|
47
|
-
|
50
|
+
before :each do
|
51
|
+
initialize_morph
|
52
|
+
initialize_another_morph
|
53
|
+
end
|
48
54
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
end
|
55
|
+
it 'should have morph_method return appropriate methods for each class' do
|
56
|
+
@morph.every = 'where'
|
57
|
+
@another_morph.no = 'where'
|
53
58
|
|
54
|
-
|
55
|
-
|
56
|
-
@another_morph.no = 'where'
|
59
|
+
@morphed_class.morph_methods.size.should == 2
|
60
|
+
@another_morphed_class.morph_methods.size.should == 2
|
57
61
|
|
58
|
-
|
59
|
-
|
62
|
+
@morphed_class.morph_methods.should == ['every','every=']
|
63
|
+
@another_morphed_class.morph_methods.should == ['no','no=']
|
64
|
+
end
|
60
65
|
|
61
|
-
|
62
|
-
|
63
|
-
|
66
|
+
it 'should call morph_attributes on both objects, when one object has a reference to another' do
|
67
|
+
@morph.every = 'which'
|
68
|
+
@another_morph.way = 'but'
|
69
|
+
@morph.loose = @another_morph
|
64
70
|
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
71
|
+
attributes = @morph.morph_attributes
|
72
|
+
attributes[:every].should == 'which'
|
73
|
+
attributes[:loose].should == {:way => 'but'}
|
74
|
+
end
|
69
75
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
76
|
+
it 'should call morph_attributes on both objects, when one object has a reference to array of others' do
|
77
|
+
@morph.every = 'which'
|
78
|
+
@another_morph.way = 'but'
|
79
|
+
@morph.loose = [@another_morph]
|
74
80
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
81
|
+
attributes = @morph.morph_attributes
|
82
|
+
attributes[:every].should == 'which'
|
83
|
+
attributes[:loose].should == [{:way => 'but'}]
|
84
|
+
end
|
79
85
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
86
|
+
it 'should call morph_attributes on both objects, when one object has a reference to hash of others' do
|
87
|
+
@morph.every = 'which'
|
88
|
+
@another_morph.way = 'but'
|
89
|
+
@morph.loose = { :honky_tonk => @another_morph}
|
84
90
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
91
|
+
attributes = @morph.morph_attributes
|
92
|
+
attributes[:every].should == 'which'
|
93
|
+
attributes[:loose].should == { :honky_tonk => {:way => 'but'} }
|
94
|
+
end
|
89
95
|
|
90
|
-
|
91
|
-
|
92
|
-
|
96
|
+
after :each do
|
97
|
+
remove_morph_methods
|
98
|
+
remove_another_morph_methods
|
99
|
+
end
|
93
100
|
end
|
94
101
|
|
95
|
-
|
96
|
-
|
97
|
-
remove_another_morph_methods
|
98
|
-
end
|
99
|
-
end
|
102
|
+
describe "when class definition contains methods and morph is included" do
|
103
|
+
include MorphSpecHelperMethods
|
100
104
|
|
101
|
-
|
102
|
-
|
105
|
+
after :all do
|
106
|
+
remove_morph_methods
|
107
|
+
@morphed_class.class_eval "remove_method :happy"
|
108
|
+
end
|
103
109
|
|
104
|
-
|
105
|
-
|
106
|
-
|
110
|
+
it 'should not return methods defined in class in morph_methods list' do
|
111
|
+
initialize_morph "class ExampleMorph\n include Morph\n def happy\n 'happy, joy, joy'\n end\n end"
|
112
|
+
morph_methods.should be_empty
|
113
|
+
end
|
107
114
|
end
|
108
115
|
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
116
|
+
describe "when writer method that didn't exist before is called with blank space attribute value" do
|
117
|
+
before :each do
|
118
|
+
remove_morph_methods
|
119
|
+
@morph.noise= ' '
|
120
|
+
@attribute = 'noise'
|
121
|
+
end
|
114
122
|
|
115
|
-
|
116
|
-
before :each do
|
117
|
-
remove_morph_methods
|
118
|
-
@morph.noise= ' '
|
119
|
-
@attribute = 'noise'
|
123
|
+
it_should_behave_like "class without generated accessor methods added"
|
120
124
|
end
|
121
125
|
|
122
|
-
|
123
|
-
end
|
126
|
+
describe 'when morph method used to set attribute value' do
|
124
127
|
|
125
|
-
|
128
|
+
before :each do
|
129
|
+
remove_morph_methods
|
130
|
+
@value = '20 Mar 2008'
|
131
|
+
@morph.morph('Reading', @value)
|
132
|
+
@attribute = 'reading'
|
133
|
+
@expected_morph_methods_count = 2
|
134
|
+
end
|
135
|
+
|
136
|
+
it_should_behave_like "class with generated accessor methods added"
|
126
137
|
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
@morph.morph('Reading', @value)
|
131
|
-
@attribute = 'reading'
|
132
|
-
@expected_morph_methods_count = 2
|
138
|
+
it 'should return assigned value when reader method called' do
|
139
|
+
@morph.reading.should == @value
|
140
|
+
end
|
133
141
|
end
|
134
142
|
|
135
|
-
|
143
|
+
describe 'when morph method used to set an attribute value hash' do
|
144
|
+
before :each do
|
145
|
+
remove_morph_methods
|
146
|
+
@attributes = [:drink,:sugars,:milk]
|
147
|
+
@morph.morph :drink => 'tea', :sugars => 2, :milk => 'yes please'
|
148
|
+
@expected_morph_methods_count = 6
|
149
|
+
end
|
136
150
|
|
137
|
-
|
138
|
-
@morph.reading.should == @value
|
139
|
-
end
|
140
|
-
end
|
151
|
+
it_should_behave_like "class with generated accessor methods added"
|
141
152
|
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
@expected_morph_methods_count = 6
|
148
|
-
end
|
153
|
+
it 'should return assigned value when reader method called' do
|
154
|
+
@morph.drink.should == 'tea'
|
155
|
+
@morph.sugars.should == 2
|
156
|
+
@morph.milk.should == 'yes please'
|
157
|
+
end
|
149
158
|
|
150
|
-
|
159
|
+
it 'should generate rails model generator script line' do
|
160
|
+
@morphed_class.script_generate.should == "ruby script/destroy rspec_model ExampleMorph; ruby script/generate rspec_model ExampleMorph drink:string milk:string sugars:string"
|
161
|
+
end
|
151
162
|
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
@morph.milk.should == 'yes please'
|
163
|
+
it 'should generate rails model generator script line' do
|
164
|
+
@morphed_class.script_generate(:generator=>'model').should == "ruby script/destroy model ExampleMorph; ruby script/generate model ExampleMorph drink:string milk:string sugars:string"
|
165
|
+
end
|
156
166
|
end
|
157
167
|
|
158
|
-
|
159
|
-
|
160
|
-
|
168
|
+
describe "when morph method used to set unicode attribute name with a value" do
|
169
|
+
before :each do
|
170
|
+
$KCODE = "u"
|
171
|
+
remove_morph_methods
|
172
|
+
@age = 19
|
173
|
+
@attribute = "年龄"
|
174
|
+
@morph.morph(@attribute, @age)
|
175
|
+
@expected_morph_methods_count = 2
|
176
|
+
end
|
161
177
|
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end
|
178
|
+
after :all do
|
179
|
+
$KCODE = "NONE"
|
180
|
+
end
|
166
181
|
|
167
|
-
|
168
|
-
before :each do
|
169
|
-
$KCODE = "u"
|
170
|
-
remove_morph_methods
|
171
|
-
@age = 19
|
172
|
-
@attribute = "年龄"
|
173
|
-
@morph.morph(@attribute, @age)
|
174
|
-
@expected_morph_methods_count = 2
|
175
|
-
end
|
182
|
+
it_should_behave_like "class with generated accessor methods added"
|
176
183
|
|
177
|
-
|
178
|
-
|
184
|
+
it 'should return assigned value when reader method called' do
|
185
|
+
@morph.send(@attribute.to_sym) == @age
|
186
|
+
end
|
179
187
|
end
|
180
188
|
|
181
|
-
|
189
|
+
describe "when morph method used to set japanese and latin unicode attribute name with a value" do
|
190
|
+
before :each do
|
191
|
+
$KCODE = "u"
|
192
|
+
remove_morph_methods
|
193
|
+
@age = 19
|
194
|
+
@attribute = "ページビュー_graph"
|
195
|
+
@morph.morph(@attribute, @age)
|
196
|
+
@expected_morph_methods_count = 2
|
197
|
+
end
|
182
198
|
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
199
|
+
after :all do
|
200
|
+
$KCODE = "NONE"
|
201
|
+
end
|
202
|
+
|
203
|
+
it_should_behave_like "class with generated accessor methods added"
|
187
204
|
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
@morph.morph('Pizza', ' ')
|
192
|
-
@attribute = 'pizza'
|
205
|
+
it 'should return assigned value when reader method called' do
|
206
|
+
@morph.send(@attribute.to_sym) == @age
|
207
|
+
end
|
193
208
|
end
|
194
209
|
|
195
|
-
|
196
|
-
|
210
|
+
describe 'when morph method used to set blank space attribute value' do
|
211
|
+
before :each do
|
212
|
+
remove_morph_methods
|
213
|
+
@morph.morph('Pizza', ' ')
|
214
|
+
@attribute = 'pizza'
|
215
|
+
end
|
197
216
|
|
198
|
-
|
199
|
-
before :each do
|
200
|
-
remove_morph_methods
|
201
|
-
@morph.morph('Pizza', nil)
|
202
|
-
@attribute = 'pizza'
|
217
|
+
it_should_behave_like "class without generated accessor methods added"
|
203
218
|
end
|
204
219
|
|
205
|
-
|
206
|
-
|
220
|
+
describe 'when morph method used to set nil attribute value' do
|
221
|
+
before :each do
|
222
|
+
remove_morph_methods
|
223
|
+
@morph.morph('Pizza', nil)
|
224
|
+
@attribute = 'pizza'
|
225
|
+
end
|
226
|
+
|
227
|
+
it_should_behave_like "class without generated accessor methods added"
|
228
|
+
end
|
207
229
|
|
208
230
|
|
209
|
-
describe
|
231
|
+
describe "when reader method that didn't exist before is called" do
|
210
232
|
|
211
|
-
|
233
|
+
include MorphSpecHelperMethods
|
212
234
|
|
213
|
-
|
214
|
-
|
215
|
-
|
235
|
+
it 'should raise NoMethodError' do
|
236
|
+
initialize_morph
|
237
|
+
lambda { @morph.noise }.should raise_error(/undefined method `noise'/)
|
238
|
+
end
|
216
239
|
end
|
217
|
-
end
|
218
240
|
|
219
|
-
describe
|
241
|
+
describe "when reader method called that didn't exist before is a class method" do
|
220
242
|
|
221
|
-
|
243
|
+
include MorphSpecHelperMethods
|
222
244
|
|
223
|
-
|
224
|
-
|
225
|
-
|
245
|
+
it 'should raise NoMethodError' do
|
246
|
+
initialize_morph
|
247
|
+
lambda { @morph.name }.should raise_error(/undefined method `name'/)
|
248
|
+
end
|
226
249
|
end
|
227
|
-
end
|
228
250
|
|
229
|
-
describe
|
251
|
+
describe "when writer method called matches a class reader method" do
|
230
252
|
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
253
|
+
before :each do
|
254
|
+
remove_morph_methods
|
255
|
+
@value = 'Morph'
|
256
|
+
@morph.name = @value
|
257
|
+
@attribute = 'name'
|
258
|
+
@expected_morph_methods_count = 2
|
259
|
+
end
|
238
260
|
|
239
|
-
|
261
|
+
it_should_behave_like "class with generated accessor methods added"
|
240
262
|
|
241
|
-
|
242
|
-
|
263
|
+
it 'should return assigned value when reader method called' do
|
264
|
+
@morph.name.should == @value
|
265
|
+
end
|
243
266
|
end
|
244
|
-
end
|
245
267
|
|
246
268
|
|
247
|
-
describe
|
269
|
+
describe "when class= is called" do
|
248
270
|
|
249
|
-
|
250
|
-
|
251
|
-
|
271
|
+
include MorphSpecHelperMethods
|
272
|
+
before :all do initialize_morph; end
|
273
|
+
after :all do remove_morph_methods; end
|
252
274
|
|
253
|
-
|
254
|
-
|
255
|
-
|
275
|
+
it 'should throw exception if non nil object is passed' do
|
276
|
+
lambda { @morph.class = 'Red' }.should raise_error(/cannot create accessor methods/)
|
277
|
+
end
|
256
278
|
|
257
|
-
|
258
|
-
|
279
|
+
it 'should throw exception if nil object is passed' do
|
280
|
+
lambda { @morph.class = nil }.should raise_error(/cannot create accessor methods/)
|
281
|
+
end
|
259
282
|
end
|
260
|
-
end
|
261
283
|
|
262
|
-
describe
|
284
|
+
describe 'when passing block to morph_method_missing' do
|
263
285
|
|
264
|
-
|
265
|
-
|
266
|
-
|
286
|
+
include MorphSpecHelperMethods
|
287
|
+
before :all do initialize_morph; end
|
288
|
+
after :each do remove_morph_methods; end
|
267
289
|
|
268
|
-
|
269
|
-
|
270
|
-
|
290
|
+
it 'should class_eval the block' do
|
291
|
+
@morph.morph_method_missing(:chunky, 'bacon') do |base, attribute|
|
292
|
+
base.class_eval "def #{attribute}; 'spinach'; end"
|
293
|
+
end
|
294
|
+
@morph.respond_to?(:chunky).should == true
|
295
|
+
@morph.chunky.should == 'spinach'
|
296
|
+
@morphed_class.class_eval "remove_method :chunky"
|
297
|
+
lambda { @morph.chunky }.should raise_error
|
271
298
|
end
|
272
|
-
@morph.respond_to?(:chunky).should == true
|
273
|
-
@morph.chunky.should == 'spinach'
|
274
|
-
@morphed_class.class_eval "remove_method :chunky"
|
275
|
-
lambda { @morph.chunky }.should raise_error
|
276
|
-
end
|
277
299
|
|
278
|
-
|
279
|
-
|
280
|
-
|
300
|
+
it 'should class_eval the block' do
|
301
|
+
@morph.morph_method_missing :chunky, 'bacon' do |base, attribute|
|
302
|
+
base.class_def(attribute) { 'spinach' }
|
303
|
+
end
|
304
|
+
@morph.respond_to?(:chunky).should == true
|
305
|
+
@morph.chunky.should == 'spinach'
|
306
|
+
@morphed_class.class_eval "remove_method :chunky"
|
307
|
+
lambda { @morph.chunky }.should raise_error
|
281
308
|
end
|
282
|
-
@morph.respond_to?(:chunky).should == true
|
283
|
-
@morph.chunky.should == 'spinach'
|
284
|
-
@morphed_class.class_eval "remove_method :chunky"
|
285
|
-
lambda { @morph.chunky }.should raise_error
|
286
|
-
end
|
287
309
|
|
288
|
-
end
|
310
|
+
end
|
289
311
|
|
290
|
-
describe
|
312
|
+
describe "when converting label text to morph method name" do
|
291
313
|
|
292
|
-
|
314
|
+
include MorphSpecHelperMethods
|
293
315
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
|
313
|
-
|
314
|
-
|
315
|
-
|
316
|
-
|
317
|
-
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
316
|
+
it 'should upper case to lower case' do
|
317
|
+
check_convert_to_morph_method_name 'CaSe', 'case'
|
318
|
+
end
|
319
|
+
it 'should convert single space to underscorce' do
|
320
|
+
check_convert_to_morph_method_name 'First reading', 'first_reading'
|
321
|
+
end
|
322
|
+
it 'should convert multiple spaces to single underscorce' do
|
323
|
+
check_convert_to_morph_method_name "First reading", 'first_reading'
|
324
|
+
end
|
325
|
+
it 'should convert tabs to single underscorce' do
|
326
|
+
check_convert_to_morph_method_name "First\t\treading", 'first_reading'
|
327
|
+
end
|
328
|
+
it 'should convert new line chars to single underscorce' do
|
329
|
+
check_convert_to_morph_method_name "First\r\nreading", 'first_reading'
|
330
|
+
end
|
331
|
+
it 'should remove leading and trailing whitespace new line chars to single underscorce' do
|
332
|
+
check_convert_to_morph_method_name " \t\r\nFirst reading \t\r\n", 'first_reading'
|
333
|
+
end
|
334
|
+
it 'should remove trailing colon surrounded by whitespace' do
|
335
|
+
check_convert_to_morph_method_name "First reading : ", 'first_reading'
|
336
|
+
end
|
337
|
+
it 'should remove parenthesis' do
|
338
|
+
check_convert_to_morph_method_name 'Nav(GBX)', 'nav_gbx'
|
339
|
+
end
|
340
|
+
it 'should remove *' do
|
341
|
+
check_convert_to_morph_method_name 'Change**', 'change'
|
342
|
+
end
|
343
|
+
it 'should convert % character to the text "percentage"' do
|
344
|
+
check_convert_to_morph_method_name '% Change', 'percentage_change'
|
345
|
+
end
|
346
|
+
it 'should precede leading digit with an underscore character' do
|
347
|
+
check_convert_to_morph_method_name '52w_high', '_52w_high'
|
348
|
+
end
|
349
|
+
it 'should handle unicode name' do
|
350
|
+
check_convert_to_morph_method_name '年龄', '年龄'
|
351
|
+
end
|
329
352
|
end
|
330
353
|
end
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../lib/morph'
|
2
|
+
|
3
|
+
module MorphSpecHelperMethods
|
4
|
+
|
5
|
+
def initialize_morph_class code=nil
|
6
|
+
code = 'class ExampleMorph; include Morph; end' unless code
|
7
|
+
eval code
|
8
|
+
@morphed_class = ExampleMorph
|
9
|
+
end
|
10
|
+
|
11
|
+
def initialize_second_morph_class code=nil
|
12
|
+
code = 'class AnotherMorph; include Morph; end' unless code
|
13
|
+
eval code
|
14
|
+
@another_morphed_class = AnotherMorph
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize_morph code=nil
|
18
|
+
initialize_morph_class code
|
19
|
+
@original_instance_methods = @morphed_class.instance_methods
|
20
|
+
@morph = @morphed_class.new
|
21
|
+
end
|
22
|
+
|
23
|
+
def initialize_another_morph
|
24
|
+
initialize_second_morph_class
|
25
|
+
@more_original_instance_methods = @another_morphed_class.instance_methods
|
26
|
+
@another_morph = @another_morphed_class.new
|
27
|
+
end
|
28
|
+
|
29
|
+
def remove_morph_methods
|
30
|
+
@morphed_class.instance_methods.each do |method|
|
31
|
+
@morphed_class.class_eval "remove_method :#{method}" unless @original_instance_methods.include?(method)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
def remove_another_morph_methods
|
36
|
+
@another_morphed_class.instance_methods.each do |method|
|
37
|
+
@another_morphed_class.class_eval "remove_method :#{method}" unless @more_original_instance_methods.include?(method)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def instance_methods
|
42
|
+
@morphed_class.instance_methods
|
43
|
+
end
|
44
|
+
|
45
|
+
def morph_methods
|
46
|
+
@morphed_class.morph_methods
|
47
|
+
end
|
48
|
+
|
49
|
+
def check_convert_to_morph_method_name label, method_name
|
50
|
+
code = 'class ExampleMorph; include Morph; def convert_to_morph_method_name label; super; end; end'
|
51
|
+
eval code
|
52
|
+
ExampleMorph.new.convert_to_morph_method_name(label).should == method_name
|
53
|
+
end
|
54
|
+
|
55
|
+
def each_attribute
|
56
|
+
if @attribute
|
57
|
+
yield @attribute
|
58
|
+
elsif @attributes
|
59
|
+
@attributes.each {|a| yield a }
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "class with generated accessor methods added", :shared => true do
|
65
|
+
|
66
|
+
include MorphSpecHelperMethods
|
67
|
+
before :all do initialize_morph; end
|
68
|
+
after :all do remove_morph_methods; end
|
69
|
+
|
70
|
+
it 'should add reader method to class instance_methods list' do
|
71
|
+
each_attribute { |a| instance_methods.should include(a.to_s) }
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'should add writer method to class instance_methods list' do
|
75
|
+
each_attribute { |a| instance_methods.should include("#{a}=") }
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should add reader method to class morph_methods list' do
|
79
|
+
each_attribute { |a| morph_methods.should include(a.to_s) }
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should add writer method to class morph_methods list' do
|
83
|
+
each_attribute { |a| morph_methods.should include("#{a}=") }
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'should only have generated accessor methods in morph_methods list' do
|
87
|
+
morph_methods.size.should == @expected_morph_methods_count
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
describe "class without generated accessor methods added", :shared => true do
|
93
|
+
include MorphSpecHelperMethods
|
94
|
+
|
95
|
+
before :all do
|
96
|
+
initialize_morph
|
97
|
+
end
|
98
|
+
|
99
|
+
after :all do
|
100
|
+
remove_morph_methods
|
101
|
+
end
|
102
|
+
|
103
|
+
it 'should not add reader method to class instance_methods list' do
|
104
|
+
instance_methods.should_not include(@attribute)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should not add writer method to class instance_methods list' do
|
108
|
+
instance_methods.should_not include("#{@attribute}=")
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'should not add reader method to class morph_methods list' do
|
112
|
+
morph_methods.should_not include(@attribute)
|
113
|
+
end
|
114
|
+
|
115
|
+
it 'should not add writer method to class morph_methods list' do
|
116
|
+
morph_methods.should_not include("#{@attribute}=")
|
117
|
+
end
|
118
|
+
|
119
|
+
it 'should have empty morph_methods list' do
|
120
|
+
morph_methods.size.should == 0
|
121
|
+
end
|
122
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: morph
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Rob McKinnon
|
@@ -9,10 +9,19 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2008-05
|
12
|
+
date: 2008-08-05 00:00:00 +01:00
|
13
13
|
default_executable:
|
14
|
-
dependencies:
|
15
|
-
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: echoe
|
17
|
+
type: :development
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
16
25
|
description: Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.
|
17
26
|
email:
|
18
27
|
- rob ~@nospam@~ rubyforge.org
|
@@ -32,9 +41,11 @@ files:
|
|
32
41
|
- LICENSE
|
33
42
|
- README
|
34
43
|
- spec/morph_spec.rb
|
44
|
+
- spec/morph_spec_helper.rb
|
35
45
|
- spec/spec.opts
|
36
46
|
- Manifest
|
37
47
|
- morph.gemspec
|
48
|
+
- Rakefile
|
38
49
|
has_rdoc: true
|
39
50
|
homepage: ""
|
40
51
|
post_install_message:
|
@@ -56,14 +67,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
56
67
|
version:
|
57
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
58
69
|
requirements:
|
59
|
-
- - "
|
70
|
+
- - "="
|
60
71
|
- !ruby/object:Gem::Version
|
61
|
-
version: "
|
72
|
+
version: "1.2"
|
62
73
|
version:
|
63
74
|
requirements: []
|
64
75
|
|
65
76
|
rubyforge_project: morph
|
66
|
-
rubygems_version: 1.
|
77
|
+
rubygems_version: 1.2.0
|
67
78
|
signing_key:
|
68
79
|
specification_version: 2
|
69
80
|
summary: Morph allows you to emerge class definitions via calling assignment methods; mix with Hpricot for screen scrapping fun.
|