gotascii-happymapper 0.1.6

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,17 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe HappyMapper::Attribute do
4
+ describe "initialization" do
5
+ before do
6
+ @attr = HappyMapper::Attribute.new(:foo, String)
7
+ end
8
+
9
+ it 'should know that it is an attribute' do
10
+ @attr.attribute?.should be_true
11
+ end
12
+
13
+ it 'should know that it is NOT an element' do
14
+ @attr.element?.should be_false
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe HappyMapper::Element do
4
+ describe "initialization" do
5
+ before do
6
+ @attr = HappyMapper::Element.new(:foo, String)
7
+ end
8
+
9
+ it 'should know that it is an element' do
10
+ @attr.element?.should be_true
11
+ end
12
+
13
+ it 'should know that it is NOT an attribute' do
14
+ @attr.attribute?.should be_false
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,73 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe HappyMapper::Item do
4
+
5
+ describe "new instance" do
6
+ before do
7
+ @attr = HappyMapper::Item.new(:foo, String, :tag => 'foobar')
8
+ end
9
+
10
+ it "should accept a name" do
11
+ @attr.name.should == 'foo'
12
+ end
13
+
14
+ it 'should accept a type' do
15
+ @attr.type.should == String
16
+ end
17
+
18
+ it 'should accept :tag as an option' do
19
+ @attr.tag.should == 'foobar'
20
+ end
21
+
22
+ it 'should provide #name' do
23
+ @attr.should respond_to(:name)
24
+ end
25
+
26
+ it 'should provide #type' do
27
+ @attr.should respond_to(:type)
28
+ end
29
+ end
30
+
31
+ describe "typecasting" do
32
+ it "should work with Strings" do
33
+ attribute = HappyMapper::Item.new(:foo, String)
34
+ [21, '21'].each do |a|
35
+ attribute.typecast(a).should == '21'
36
+ end
37
+ end
38
+
39
+ it "should work with Integers" do
40
+ attribute = HappyMapper::Item.new(:foo, Integer)
41
+ [21, 21.0, '21'].each do |a|
42
+ attribute.typecast(a).should == 21
43
+ end
44
+ end
45
+
46
+ it "should work with Floats" do
47
+ attribute = HappyMapper::Item.new(:foo, Float)
48
+ [21, 21.0, '21'].each do |a|
49
+ attribute.typecast(a).should == 21.0
50
+ end
51
+ end
52
+
53
+ it "should work with Times" do
54
+ attribute = HappyMapper::Item.new(:foo, Time)
55
+ attribute.typecast('2000-01-01 01:01:01.123456').should == Time.local(2000, 1, 1, 1, 1, 1, 123456)
56
+ end
57
+
58
+ it "should work with Dates" do
59
+ attribute = HappyMapper::Item.new(:foo, Date)
60
+ attribute.typecast('2000-01-01').should == Date.new(2000, 1, 1)
61
+ end
62
+
63
+ it "should work with DateTimes" do
64
+ attribute = HappyMapper::Item.new(:foo, DateTime)
65
+ attribute.typecast('2000-01-01 00:00:00').should == DateTime.new(2000, 1, 1, 0, 0, 0)
66
+ end
67
+
68
+ it "should work with Boolean" do
69
+ attribute = HappyMapper::Item.new(:foo, Boolean)
70
+ attribute.typecast('false').should == false
71
+ end
72
+ end
73
+ end
@@ -0,0 +1,294 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ class Place
4
+ include HappyMapper
5
+
6
+ element :name, String
7
+ end
8
+
9
+ class Radar
10
+ include HappyMapper
11
+ has_many :places, Place
12
+ end
13
+
14
+ class Post
15
+ include HappyMapper
16
+
17
+ attribute :href, String
18
+ attribute :hash, String
19
+ attribute :description, String
20
+ attribute :tag, String
21
+ attribute :time, Time
22
+ attribute :others, Integer
23
+ attribute :extended, String
24
+ end
25
+
26
+ class User
27
+ include HappyMapper
28
+
29
+ element :id, Integer
30
+ element :name, String
31
+ element :screen_name, String
32
+ element :location, String
33
+ element :description, String
34
+ element :profile_image_url, String
35
+ element :url, String
36
+ element :protected, Boolean
37
+ element :followers_count, Integer
38
+ end
39
+
40
+ class Status
41
+ include HappyMapper
42
+
43
+ element :id, Integer
44
+ element :text, String
45
+ element :created_at, Time
46
+ element :source, String
47
+ element :truncated, Boolean
48
+ element :in_reply_to_status_id, Integer
49
+ element :in_reply_to_user_id, Integer
50
+ element :favorited, Boolean
51
+ has_one :user, User
52
+ end
53
+
54
+ class CurrentWeather
55
+ include HappyMapper
56
+ tag 'aws:ob'
57
+ element :temperature, Integer, :tag => 'aws:temp'
58
+ element :feels_like, Integer, :tag => 'aws:feels-like'
59
+ element :current_condition, String, :tag => 'aws:current-condition', :attributes => {:icon => String}
60
+ end
61
+
62
+ class Address
63
+ include HappyMapper
64
+
65
+ element :street, String
66
+ element :postcode, String
67
+ element :housenumber, String
68
+ element :city, String
69
+ element :country, String
70
+ end
71
+
72
+ module PITA
73
+ class Item
74
+ include HappyMapper
75
+
76
+ tag 'Item' # if you put class in module you need tag
77
+ element :asin, String, :tag => 'ASIN'
78
+ element :detail_page_url, String, :tag => 'DetailPageURL'
79
+ element :manufacturer, String, :tag => 'Manufacturer', :deep => true
80
+ end
81
+
82
+ class Items
83
+ include HappyMapper
84
+
85
+ tag 'Items' # if you put class in module you need tag
86
+ element :total_results, Integer, :tag => 'TotalResults'
87
+ element :total_pages, Integer, :tag => 'TotalPages'
88
+ has_many :items, Item
89
+ end
90
+ end
91
+
92
+ describe HappyMapper do
93
+
94
+ describe "being included into another class" do
95
+ before do
96
+ Foo.instance_variable_set("@attributes", {})
97
+ Foo.instance_variable_set("@elements", {})
98
+ end
99
+ class Foo; include HappyMapper end
100
+
101
+ it "should set attributes to an array" do
102
+ Foo.attributes.should == []
103
+ end
104
+
105
+ it "should set @elements to a hash" do
106
+ Foo.elements.should == []
107
+ end
108
+
109
+ it "should allow adding an attribute" do
110
+ lambda {
111
+ Foo.attribute :name, String
112
+ }.should change(Foo, :attributes)
113
+ end
114
+
115
+ it "should be able to get all attributes in array" do
116
+ Foo.attribute :name, String
117
+ Foo.attributes.size.should == 1
118
+ end
119
+
120
+ it "should allow adding an element" do
121
+ lambda {
122
+ Foo.element :name, String
123
+ }.should change(Foo, :elements)
124
+ end
125
+
126
+ it "should be able to get all elements in array" do
127
+ Foo.element(:name, String)
128
+ Foo.elements.size.should == 1
129
+ end
130
+
131
+ it "should allow has one association" do
132
+ Foo.has_one(:user, User)
133
+ element = Foo.elements.first
134
+ element.name.should == 'user'
135
+ element.type.should == User
136
+ element.options[:single] = true
137
+ end
138
+
139
+ it "should allow has many association" do
140
+ Foo.has_many(:users, User)
141
+ element = Foo.elements.first
142
+ element.name.should == 'users'
143
+ element.type.should == User
144
+ element.options[:single] = false
145
+ end
146
+
147
+ it "should default tag name to class" do
148
+ Foo.get_tag_name.should == 'foo'
149
+ end
150
+
151
+ it "should allow setting tag name" do
152
+ Foo.tag('FooBar')
153
+ Foo.get_tag_name.should == 'FooBar'
154
+ end
155
+
156
+ it "should provide #parse" do
157
+ Foo.should respond_to(:parse)
158
+ end
159
+ end
160
+
161
+ describe "#attributes" do
162
+ it "should only return attributes for the current class" do
163
+ Post.attributes.size.should == 7
164
+ Status.attributes.size.should == 0
165
+ end
166
+ end
167
+
168
+ describe "#elements" do
169
+ it "should only return elements for the current class" do
170
+ Post.elements.size.should == 0
171
+ Status.elements.size.should == 9
172
+ end
173
+ end
174
+
175
+ describe "#parse (with xml attributes mapping to ruby attributes)" do
176
+ before do
177
+ @posts = Post.parse(File.read(File.dirname(__FILE__) + '/fixtures/posts.xml'))
178
+ end
179
+
180
+ it "should get the correct number of elements" do
181
+ @posts.size.should == 20
182
+ end
183
+
184
+ it "should properly create objects" do
185
+ first = @posts.first
186
+ first.href.should == 'http://roxml.rubyforge.org/'
187
+ first.hash.should == '19bba2ab667be03a19f67fb67dc56917'
188
+ first.description.should == 'ROXML - Ruby Object to XML Mapping Library'
189
+ first.tag.should == 'ruby xml gems mapping'
190
+ first.time.should == Time.utc(2008, 8, 9, 5, 24, 20)
191
+ first.others.should == 56
192
+ first.extended.should == 'ROXML is a Ruby library designed to make it easier for Ruby developers to work with XML. Using simple annotations, it enables Ruby classes to be custom-mapped to XML. ROXML takes care of the marshalling and unmarshalling of mapped attributes so that developers can focus on building first-class Ruby classes.'
193
+ end
194
+ end
195
+
196
+ describe "#parse (with xml elements mapping to ruby attributes)" do
197
+ before do
198
+ @statuses = Status.parse(File.read(File.dirname(__FILE__) + '/fixtures/statuses.xml'))
199
+ end
200
+
201
+ it "should get the correct number of elements" do
202
+ @statuses.size.should == 20
203
+ end
204
+
205
+ it "should properly create objects" do
206
+ first = @statuses.first
207
+ first.id.should == 882281424
208
+ first.created_at.should == Time.utc(2008, 8, 9, 5, 38, 12)
209
+ first.source.should == 'web'
210
+ first.truncated.should be_false
211
+ first.in_reply_to_status_id.should == 1234
212
+ first.in_reply_to_user_id.should == 12345
213
+ first.favorited.should be_false
214
+ first.user.id.should == 4243
215
+ first.user.name.should == 'John Nunemaker'
216
+ first.user.screen_name.should == 'jnunemaker'
217
+ first.user.location.should == 'Mishawaka, IN, US'
218
+ first.user.description.should == 'Loves his wife, ruby, notre dame football and iu basketball'
219
+ first.user.profile_image_url.should == 'http://s3.amazonaws.com/twitter_production/profile_images/53781608/Photo_75_normal.jpg'
220
+ first.user.url.should == 'http://addictedtonew.com'
221
+ first.user.protected.should be_false
222
+ first.user.followers_count.should == 486
223
+ end
224
+ end
225
+
226
+ describe "#parse (with xml containing the desired element as root node)" do
227
+ before do
228
+ file_contents = File.read(File.dirname(__FILE__) + '/fixtures/address.xml')
229
+ @address = Address.parse(file_contents, :single => true)
230
+ end
231
+
232
+ it "should properly create objects" do
233
+ @address.street.should == 'Milchstrasse'
234
+ @address.postcode.should == '26131'
235
+ @address.housenumber.should == '23'
236
+ @address.city.should == 'Oldenburg'
237
+ @address.country.should == 'Germany'
238
+ end
239
+ end
240
+
241
+ # TODO: someone please get xml with namespaces working, kthxbai
242
+ describe "#parse (with xml that has namespace)" do
243
+ before do
244
+ file_contents = File.read(File.dirname(__FILE__) + '/fixtures/pita.xml')
245
+ @items = PITA::Items.parse(file_contents, :single => true, :use_default_namespace => true)
246
+ end
247
+
248
+ it "should properly create objects" do
249
+ @items.total_results.should == 22
250
+ @items.total_pages.should == 3
251
+ first = @items.items[0]
252
+ second = @items.items[1]
253
+ first.asin.should == '0321480791'
254
+ first.detail_page_url.should == 'http://www.amazon.com/gp/redirect.html%3FASIN=0321480791%26tag=ws%26lcode=xm2%26cID=2025%26ccmID=165953%26location=/o/ASIN/0321480791%253FSubscriptionId=dontbeaswoosh'
255
+ first.manufacturer.should == 'Addison-Wesley Professional'
256
+ second.asin.should == '047022388X'
257
+ second.manufacturer.should == 'Wrox'
258
+ end
259
+ end
260
+
261
+ describe "#parse (with xml that has attributes of elements)" do
262
+ before do
263
+ file_contents = File.read(File.dirname(__FILE__) + '/fixtures/current_weather.xml')
264
+ @items = CurrentWeather.parse(file_contents)
265
+ end
266
+
267
+ it "should properly create objects" do
268
+ @first = @items[0]
269
+ @first.temperature.should == 51
270
+ @first.feels_like.should == 51
271
+ @first.current_condition.should == 'Sunny'
272
+ @first.current_condition.icon.should == 'http://deskwx.weatherbug.com/images/Forecast/icons/cond007.gif'
273
+ end
274
+ end
275
+
276
+ describe "#parse (with xml that has nested elements)" do
277
+ before do
278
+ file_contents = File.read(File.dirname(__FILE__) + '/fixtures/radar.xml')
279
+ @radars = Radar.parse(file_contents)
280
+ end
281
+
282
+ it "should properly create objects" do
283
+ @first = @radars[0]
284
+ @first.places.count.should == 1
285
+ @first.places[0].name.should == 'Store'
286
+ @second = @radars[1]
287
+ @second.places.count.should == 0
288
+ @third = @radars[2]
289
+ @third.places.count.should == 2
290
+ @third.places[0].name.should == 'Work'
291
+ @third.places[1].name.should == 'Home'
292
+ end
293
+ end
294
+ end
data/spec/spec.opts ADDED
@@ -0,0 +1 @@
1
+ --colour
@@ -0,0 +1,9 @@
1
+ begin
2
+ require 'spec'
3
+ rescue LoadError
4
+ require 'rubygems'
5
+ gem 'rspec'
6
+ require 'spec'
7
+ end
8
+
9
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'happymapper')
@@ -0,0 +1,43 @@
1
+ desc 'Preps the gem for a new release'
2
+ task :prepare do
3
+ require 'rio'
4
+ Rake::Task['manifest:refresh'].invoke
5
+ gemspec = %x[rake debug_gem]
6
+ lines = gemspec.split("\n")
7
+ rio('happymapper.gemspec') < lines[1, lines.length-1].join("\n")
8
+ end
9
+
10
+ desc 'Release the website and new gem version'
11
+ task :deploy => [:check_version, :website, :release] do
12
+ puts "Remember to create SVN tag:"
13
+ puts "svn copy svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/trunk " +
14
+ "svn+ssh://#{rubyforge_username}@rubyforge.org/var/svn/#{PATH}/tags/REL-#{VERS} "
15
+ puts "Suggested comment:"
16
+ puts "Tagging release #{CHANGES}"
17
+ end
18
+
19
+ desc 'Runs tasks website_generate and install_gem as a local deployment of the gem'
20
+ task :local_deploy => [:website_generate, :install_gem]
21
+
22
+ task :check_version do
23
+ unless ENV['VERSION']
24
+ puts 'Must pass a VERSION=x.y.z release version'
25
+ exit
26
+ end
27
+ unless ENV['VERSION'] == VERS
28
+ puts "Please update your version.rb to match the release version, currently #{VERS}"
29
+ exit
30
+ end
31
+ end
32
+
33
+ desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
34
+ task :install_gem_no_doc => [:clean, :package] do
35
+ sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
36
+ end
37
+
38
+ namespace :manifest do
39
+ desc 'Recreate Manifest.txt to include ALL files'
40
+ task :refresh do
41
+ `rake check_manifest | patch -p0 > Manifest.txt`
42
+ end
43
+ end