flickrmocks 0.8.5

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.
Files changed (68) hide show
  1. data/.autotest +36 -0
  2. data/.document +5 -0
  3. data/.gitignore +23 -0
  4. data/.rspec +3 -0
  5. data/MIT-LICENSE +20 -0
  6. data/README.rdoc +59 -0
  7. data/Rakefile +76 -0
  8. data/VERSION +1 -0
  9. data/autotest/discover.rb +1 -0
  10. data/flickrmocks.gemspec +155 -0
  11. data/lib/flickr_mocks/api/api.rb +42 -0
  12. data/lib/flickr_mocks/api/flickr.rb +27 -0
  13. data/lib/flickr_mocks/api/helpers.rb +19 -0
  14. data/lib/flickr_mocks/api/options.rb +55 -0
  15. data/lib/flickr_mocks/api/sanitize.rb +29 -0
  16. data/lib/flickr_mocks/fixtures.rb +35 -0
  17. data/lib/flickr_mocks/flickraw/custom_clone.rb +19 -0
  18. data/lib/flickr_mocks/flickraw/custom_compare.rb +25 -0
  19. data/lib/flickr_mocks/flickraw/custom_marshal.rb +39 -0
  20. data/lib/flickr_mocks/flickraw/flickraw.rb +14 -0
  21. data/lib/flickr_mocks/helpers.rb +52 -0
  22. data/lib/flickr_mocks/models/helpers.rb +14 -0
  23. data/lib/flickr_mocks/models/photo.rb +101 -0
  24. data/lib/flickr_mocks/models/photo_details.rb +86 -0
  25. data/lib/flickr_mocks/models/photo_dimensions.rb +103 -0
  26. data/lib/flickr_mocks/models/photo_search.rb +115 -0
  27. data/lib/flickr_mocks/models/photo_size.rb +60 -0
  28. data/lib/flickr_mocks/models/photo_sizes.rb +93 -0
  29. data/lib/flickr_mocks/models/photos.rb +133 -0
  30. data/lib/flickr_mocks/stubs.rb +103 -0
  31. data/lib/flickr_mocks/version.rb +4 -0
  32. data/lib/flickrmocks.rb +27 -0
  33. data/spec/api/api_spec.rb +84 -0
  34. data/spec/api/flickr_spec.rb +48 -0
  35. data/spec/api/helper_spec.rb +37 -0
  36. data/spec/api/options_spec.rb +152 -0
  37. data/spec/api/sanitize_spec.rb +90 -0
  38. data/spec/base/fixtures_spec.rb +89 -0
  39. data/spec/base/flickraw/custom_clone_spec.rb +70 -0
  40. data/spec/base/flickraw/custom_compare_spec.rb +98 -0
  41. data/spec/base/flickraw/custom_marshal_spec.rb +45 -0
  42. data/spec/base/helpers_spec.rb +63 -0
  43. data/spec/base/stubs_spec.rb +180 -0
  44. data/spec/base/version_spec.rb +15 -0
  45. data/spec/fixtures/author_photos.marshal +0 -0
  46. data/spec/fixtures/empty_photos.marshal +0 -0
  47. data/spec/fixtures/expected_methods.marshal +17 -0
  48. data/spec/fixtures/interesting_photos.marshal +0 -0
  49. data/spec/fixtures/photo.marshal +0 -0
  50. data/spec/fixtures/photo_details.marshal +0 -0
  51. data/spec/fixtures/photo_size.marshal +0 -0
  52. data/spec/fixtures/photo_sizes.marshal +0 -0
  53. data/spec/fixtures/photos.marshal +0 -0
  54. data/spec/models/helpers_spec.rb +25 -0
  55. data/spec/models/photo_details_spec.rb +224 -0
  56. data/spec/models/photo_dimensions_spec.rb +208 -0
  57. data/spec/models/photo_search_spec.rb +255 -0
  58. data/spec/models/photo_size_spec.rb +122 -0
  59. data/spec/models/photo_sizes_spec.rb +168 -0
  60. data/spec/models/photo_spec.rb +278 -0
  61. data/spec/models/photos_spec.rb +305 -0
  62. data/spec/shared_examples/array_accessor.rb +157 -0
  63. data/spec/shared_examples/collection.rb +49 -0
  64. data/spec/shared_examples/image_url_helpers.rb +56 -0
  65. data/spec/shared_examples/size_accessor.rb +13 -0
  66. data/spec/spec_helper.rb +24 -0
  67. data/tasks/fixtures.rb +164 -0
  68. metadata +259 -0
@@ -0,0 +1,224 @@
1
+ require 'spec_helper'
2
+
3
+ describe APP::PhotoDetails do
4
+ let(:klass){APP::PhotoDetails}
5
+ let(:fixtures){APP::Fixtures.new}
6
+
7
+ let(:basic_photo) { APP::Photo.new fixtures.photo }
8
+ let(:extended_photo) { APP::Photo.new fixtures.photo_details }
9
+ let(:photo_sizes) { APP::PhotoSizes.new fixtures.photo_sizes }
10
+
11
+ let(:photo_details_basic){klass.new(basic_photo,photo_sizes)}
12
+ let(:photo_details_extended){klass.new(extended_photo,photo_sizes)}
13
+
14
+
15
+ describe "initialization" do
16
+ it "returns object of proper class when extended PhotoDetails and PhotoSizes supplied" do
17
+ klass.new(extended_photo,photo_sizes).should be_a(klass)
18
+ end
19
+ it "returns object of proper class when basic PhotoDetails and PhotoSizes supplied" do
20
+ klass.new(basic_photo,photo_sizes).should be_a(klass)
21
+ end
22
+ it "returns object of expected class when proper flickr responses supplied for sizes and photo" do
23
+ klass.new(fixtures.photo_details,fixtures.photo_sizes).should be_a(klass)
24
+ end
25
+ it "raises an error when Array supplied for photo" do
26
+ lambda{APP::PhotoDetails.new [],photo_sizes}.should raise_error ArgumentError
27
+ end
28
+ it "raises an error when Array supplied for photo_details" do
29
+ lambda{APP::PhotoDetails.new extended_photo,[]}.should raise_error ArgumentError
30
+ end
31
+ it "raises error when nil supplied for photo_sizes" do
32
+ lambda{APP::PhotoDetails.new extended_photo,nil}.should raise_error ArgumentError
33
+ end
34
+ it "raises error when nil supplied for photo_details" do
35
+ lambda{APP::PhotoDetails.new nil,photo_sizes}.should raise_error ArgumentError
36
+ end
37
+ end
38
+
39
+ context "instance methods" do
40
+ subject {photo_details_extended}
41
+ specify {subject.should respond_to(:owner_name)}
42
+ context "#owner_name" do
43
+ it "returns expected name for owner" do
44
+ subject.owner_name.should == fixtures.photo_details.owner.realname
45
+ end
46
+ end
47
+
48
+ specify {subject.should respond_to(:owner_username)}
49
+ context "#owner_username" do
50
+ it "returns expected name for owner" do
51
+ subject.owner_username.should == fixtures.photo_details.owner.username
52
+ end
53
+ end
54
+
55
+ specify {subject.should respond_to(:dimensions)}
56
+ context "#dimensions" do
57
+ it "returns expected PhotoSize object" do
58
+ subject.dimensions.should == photo_sizes
59
+ end
60
+ end
61
+
62
+ specify {subject.should respond_to(:possible_sizes)}
63
+ context "#possible_sizes" do
64
+ it "returns list of all possible sizes" do
65
+ subject.possible_sizes.should == FlickrMocks::Models::Helpers.possible_sizes
66
+ end
67
+ end
68
+
69
+ specify {subject.should respond_to(:photo)}
70
+ context "#photo" do
71
+ it "returns expected Photo object when basic photo" do
72
+ subject.photo.should == extended_photo
73
+ end
74
+ end
75
+
76
+ specify {subject.should respond_to(:==)}
77
+ context "#==" do
78
+ it "returns true when object is compared to itself" do
79
+ subject.should == subject
80
+ end
81
+ it "returns true when object is compared to clone of itself" do
82
+ subject.should == subject.clone
83
+ end
84
+ it "returns false when object is compared to an Array" do
85
+ subject.should_not == [1,2,3]
86
+ end
87
+ it "returns false when a single dimension is different" do
88
+ other = subject.clone
89
+ other.dimensions[0].instance_eval('@delegated_to_object').instance_eval('@h["width"]=-22')
90
+ subject.should_not == other
91
+ end
92
+ it "returns false when a single photo attribute is different" do
93
+ other = subject.clone
94
+ subject.photo.instance_eval('@delegated_to_object').instance_eval('@h["farm"]=-22')
95
+ subject.should_not == other
96
+ end
97
+ end
98
+
99
+ context "methods that are delegated to photo object" do
100
+ context "basic photo object" do
101
+ subject {photo_details_basic}
102
+ it "returns expected result delegated to non-url helpers for basic photo" do
103
+ subject.photo.delegated_instance_methods.each do |method|
104
+ subject.send(method).should == subject.photo.send(method)
105
+ end
106
+ end
107
+ it "returns expected result delegated to url helpers for basic photo" do
108
+ reference = APP::Photo.new(fixtures.photo)
109
+ FlickrMocks::Models::Helpers.possible_sizes.each do |size|
110
+ subject.send(size).should == reference.send(size)
111
+ end
112
+ end
113
+ end
114
+ context "detailed photo object" do
115
+ subject {photo_details_extended}
116
+ eval('specify {subject.should respond_to(:id)}')
117
+ it "returns expected result for basic delegated photos" do
118
+ subject.photo.delegated_instance_methods.each do |method|
119
+ subject.send(method).should == subject.photo.send(method)
120
+ end
121
+ end
122
+ it "returns expected result delegated to url helpers for detailed photo" do
123
+ reference = APP::Photo.new(fixtures.photo_details)
124
+ FlickrMocks::Models::Helpers.possible_sizes.each do |size|
125
+ subject.send(size).should == reference.send(size)
126
+ end
127
+ end
128
+ end
129
+ end
130
+
131
+ context "iteration methods delegated to dimensions (PhotoSizes)" do
132
+ let(:reference){photo_sizes}
133
+ it_should_behave_like "object with delegated Array accessor helpers"
134
+ end
135
+ end
136
+
137
+
138
+ context "metaprogramming methods" do
139
+ context "#respond_to?" do
140
+ context "with basic photo" do
141
+ subject {photo_details_basic}
142
+ specify {subject.should respond_to(:respond_to?)}
143
+ it "returns true for all methods including the ones that are delegated to sizes and basic photo" do
144
+ subject.methods.each do |method|
145
+ subject.should respond_to(method)
146
+ end
147
+ end
148
+ end
149
+
150
+ context "with extended photo" do
151
+ subject {photo_details_extended}
152
+ specify {subject.should respond_to(:respond_to?)}
153
+ it "returns true for all methods including the ones that are delegated to sizes and extended photo" do
154
+ subject.methods.each do |method|
155
+ subject.should respond_to(method)
156
+ end
157
+ end
158
+ end
159
+ end
160
+
161
+ context "#methods" do
162
+ context "with basic photo" do
163
+ subject {photo_details_basic}
164
+ specify {subject.should respond_to(:methods)}
165
+ it "resturns methods including those delegated to sizes and basic photo" do
166
+ subject.methods.sort.should == (subject.old_methods + subject.delegated_instance_methods).sort
167
+ end
168
+ end
169
+
170
+ context "with extended photo" do
171
+ subject {photo_details_extended}
172
+ specify {subject.should respond_to(:methods)}
173
+ it "returns methods including those delegated to sizes and extended photo" do
174
+ subject.methods.sort.should == (subject.old_methods + subject.delegated_instance_methods).sort
175
+ end
176
+ end
177
+ end
178
+
179
+ context "#delegated_instance_methods" do
180
+ context "with basic photo" do
181
+ subject {photo_details_basic}
182
+ specify {subject.should respond_to(:delegated_instance_methods)}
183
+ it "returns methods including those delegated to sizes and basic photo" do
184
+ subject.delegated_instance_methods.sort.should ==
185
+ (subject.photo.delegated_instance_methods +
186
+ FlickrMocks::Models::Helpers.array_accessor_methods +
187
+ FlickrMocks::Models::Helpers.possible_sizes +
188
+ [:owner_id]).sort
189
+ end
190
+ end
191
+ context "with extended photo" do
192
+ subject {photo_details_extended}
193
+ specify {subject.should respond_to(:delegated_instance_methods)}
194
+ it "returns methods including those delegated to sizes and extended photo" do
195
+ subject.delegated_instance_methods.sort.should ==
196
+ (subject.photo.delegated_instance_methods +
197
+ FlickrMocks::Models::Helpers.array_accessor_methods +
198
+ FlickrMocks::Models::Helpers.possible_sizes +
199
+ [:owner_id]).sort
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+
206
+ context "custom cloning methods" do
207
+ subject{photo_details_extended}
208
+ context "#initialize_copy" do
209
+ it "returns cloned object with distinct __id__ for dimensions" do
210
+ subject.dimensions.__id__.should_not == subject.clone.dimensions.__id__
211
+ end
212
+ it "returns cloned object with distinct __id__ for photo" do
213
+ subject.instance_eval('@delegated_to_object.__id__').should_not ==
214
+ subject.clone.instance_eval('@delegated_to_object.__id__')
215
+ end
216
+ end
217
+ end
218
+
219
+ end
220
+
221
+
222
+
223
+
224
+
@@ -0,0 +1,208 @@
1
+ require 'spec_helper'
2
+
3
+ describe APP::PhotoDimensions do
4
+ let(:dimensions_string) {'square:1x11,thumbnail:2x12,small:3x13,medium:4x14,medium_640:5x15,large:6x16,original:7x17'}
5
+ let(:expected_sizes) { [:square, :thumbnail, :small, :medium,:medium_640, :large, :original] }
6
+ let(:klass) {APP::PhotoDimensions}
7
+
8
+ subject { APP::PhotoDimensions.new(dimensions_string) }
9
+
10
+ context "class methods" do
11
+ specify {klass.should respond_to(:regexp_size)}
12
+ context "regexp_size" do
13
+ it "returns match when provided with valid string such as: 'square:1x11,thumbnail:2x12'" do
14
+ klass.regexp_size.match('square:1x11,thumbnail:2x12').should_not be_nil
15
+ end
16
+ it "returns nil when string contains an extra comma" do
17
+ klass.regexp_size.match('square:1x11,thumbnail:2x12,').should be_nil
18
+ end
19
+ it "returns nil when string is missing a comma" do
20
+ klass.regexp_size.match('square1x11,thumbnail:2x12').should be_nil
21
+ end
22
+ end
23
+ end
24
+
25
+ context "initialize" do
26
+ context "valid initialization strings" do
27
+ it "returns object of proper class with valid string" do
28
+ klass.new('square:1x11,thumbnail:2x12,small:3x13,medium:4x14,medium_640:5x15,large:6x16,original:7x17').class.should == klass
29
+ end
30
+ it "returns object of proper class with string containing only a single dimension" do
31
+ klass.new('medium:4x14').class.should == klass
32
+ end
33
+ end
34
+
35
+ context "initialization with invalid arguments" do
36
+ it "raises exception when string contains invalid size" do
37
+ lambda {klass.new('square:1x11,howdy:2x12')}.should raise_error(ArgumentError)
38
+ end
39
+ it "raises exception when string contains extraneous comma" do
40
+ lambda {klass.new('square:1x11,thumbnail:3x2,')}.should raise_error(ArgumentError)
41
+ end
42
+ it "raises exception when argument does not respond to to_s method" do
43
+ lambda {klass.new('square:1x11,thumbnail:3x2'.stub(:to_s).and_return(nil))}.should raise_error(ArgumentError)
44
+ end
45
+ end
46
+ end
47
+
48
+ context "instance methods" do
49
+ specify {subject.should respond_to(:available_sizes)}
50
+ context "#available_sizes" do
51
+ it "returns list of available sizes" do
52
+ subject.available_sizes.should == expected_sizes
53
+ end
54
+ end
55
+
56
+ specify {subject.should respond_to(:collection)}
57
+ context "#collection" do
58
+ let(:reference){
59
+ OpenStruct.new :current_page => 1,
60
+ :per_page => subject.available_sizes.length,
61
+ :total_entries => subject.available_sizes.length,
62
+ :collection => subject.dimensions
63
+ }
64
+ it_behaves_like "object that responds to collection"
65
+ end
66
+
67
+ specify {subject.should respond_to(:to_s)}
68
+ describe "#to_s method" do
69
+ it "returns expected string that represents the size and dimensions of the photo" do
70
+ subject.to_s.should == dimensions_string
71
+ end
72
+ end
73
+
74
+ specify {subject.should respond_to(:==)}
75
+ context "#==" do
76
+ it "returns true when object compared to itself" do
77
+ subject.should == subject
78
+ end
79
+ it "returns true when object compared to clone of itself" do
80
+ subject.should == subject.clone
81
+ end
82
+ it "returns false when single element is different" do
83
+ other = subject.clone
84
+ other.first.width=77123
85
+ subject.should_not == other
86
+ end
87
+ end
88
+
89
+ specify {subject.should respond_to(:possible_sizes)}
90
+ context "#possible_sizes" do
91
+ it "returns expected set of sizes" do
92
+ subject.possible_sizes.should == FlickrMocks::Models::Helpers.possible_sizes
93
+ end
94
+ end
95
+
96
+
97
+ context "size methods" do
98
+ context "fully specified dimension" do
99
+ let(:dimensions) {[[1,11],[2,12],[3,13],[4,14],[5,15],[6,16],[7,17]]}
100
+ def reference
101
+ index = expected_sizes.find_index(size)
102
+ OpenStruct.new :size => size,
103
+ :width => dimensions[index][0],
104
+ :height => dimensions[index][1]
105
+ end
106
+
107
+ specify{subject.should respond_to(:square)}
108
+ context "#square" do
109
+ let(:size){:square}
110
+ it_behaves_like "object with size accessor"
111
+ end
112
+
113
+ specify{subject.should respond_to(:thumbnail)}
114
+ context "#thumbnail" do
115
+ let(:size){:thumbnail}
116
+ it_behaves_like "object with size accessor"
117
+ end
118
+
119
+ specify{subject.should respond_to(:small)}
120
+ context "#small" do
121
+ let(:size){:small}
122
+ it_behaves_like "object with size accessor"
123
+ end
124
+
125
+ specify{subject.should respond_to(:medium)}
126
+ context "#medium" do
127
+ let(:size){:medium}
128
+ it_behaves_like "object with size accessor"
129
+ end
130
+
131
+ specify{subject.should respond_to(:medium_640)}
132
+ context "#medium_640" do
133
+ let(:size){:medium_640}
134
+ it_behaves_like "object with size accessor"
135
+ end
136
+
137
+ specify{subject.should respond_to(:large)}
138
+ context "#large" do
139
+ let(:size){:large}
140
+ it_behaves_like "object with size accessor"
141
+ end
142
+
143
+ specify{subject.should respond_to(:original)}
144
+ context "#large" do
145
+ let(:size){:original}
146
+ it_behaves_like "object with size accessor"
147
+ end
148
+ end
149
+
150
+ context "partially specified dimensions" do
151
+ subject {APP::PhotoDimensions.new('square:1x11')}
152
+ it "should return object for dimensions that are specified" do
153
+ subject.send(:square).should_not be_nil
154
+ end
155
+ it "should return nil for dimensions that are not specified" do
156
+ [:thumbnail, :small, :medium,:medium_640, :large, :original].each do |method|
157
+ subject.send(method).should be_nil
158
+ end
159
+ end
160
+ end
161
+ end
162
+
163
+ context "iteratable methods" do
164
+ let(:reference){subject.dimensions}
165
+ it_behaves_like "object with delegated Array accessor helpers"
166
+ end
167
+
168
+
169
+ end
170
+
171
+ context "metapragramming methods" do
172
+ specify {subject.should respond_to(:methods)}
173
+ context "#methods" do
174
+ it "returns expected set of methods" do
175
+ subject.methods.sort.should == (subject.old_methods +
176
+ subject.delegated_instance_methods +
177
+ subject.possible_sizes).sort
178
+ end
179
+ end
180
+
181
+ specify {subject.should respond_to(:respond_to?)}
182
+ context "#respond_to?" do
183
+ it "returns true with return value from methods" do
184
+ subject.methods.each do |method|
185
+ subject.should respond_to(method)
186
+ end
187
+ end
188
+
189
+ specify {subject.should respond_to(:delegated_instance_methods)}
190
+ context "#delegated_instance_methods" do
191
+ it "returns methods that include array accessors" do
192
+ subject.delegated_instance_methods.sort.should == (
193
+ FlickrMocks::Models::Helpers.array_accessor_methods ).sort
194
+ end
195
+ end
196
+ end
197
+ end
198
+
199
+ context "custom cloning methods" do
200
+ context "#initialize_copy" do
201
+ it "returns cloned object that has distinct id as compared with original"do
202
+ subject.dimensions.each.map do |value| value.__id__ end.should_not ==
203
+ subject.clone.dimensions.each.map do |value| value.__id__ end
204
+ end
205
+ end
206
+ end
207
+ end
208
+
@@ -0,0 +1,255 @@
1
+ require 'spec_helper'
2
+
3
+ describe APP::PhotoSearch do
4
+ let(:api) {APP::Api}
5
+ let(:klass) {APP::PhotoSearch}
6
+ let(:fixtures){APP::Fixtures.new}
7
+ let(:options) {{:search_terms => 'iran', :page => '20', :date => '2010-10-03'}}
8
+
9
+ subject { klass.new fixtures.photos,options }
10
+
11
+ context "class instance variables" do
12
+ specify {klass.should respond_to(:defaults)}
13
+ context "defaults" do
14
+ it "returns expected set of defaults" do
15
+ klass.defaults.should == {:page => 1}
16
+ end
17
+ end
18
+
19
+ specify {klass.should respond_to(:delegated_instance_methods)}
20
+ it "returns expected set of methods" do
21
+ klass.delegated_instance_methods.sort.should == [:current_page, :per_page,
22
+ :total_entries,:perpage, :capped?, :max_entries, :collection,:capped_entries].sort
23
+ end
24
+ end
25
+
26
+ context "initialization" do
27
+ context "photos argument" do
28
+ let(:options){{:search_terms => 'shiraz,iran',:page => 1,:date => '2010-09-10'}}
29
+ it "returns object of proper class when photos responselist object specified" do
30
+ klass.new(fixtures.photos, options).class.should == klass
31
+ end
32
+ it "returns object of proper class when APP::Photos object is provided" do
33
+ klass.new(APP::Photos.new(fixtures.photos),options).class.should == klass
34
+ end
35
+ it "raises an error when an array is provided" do
36
+ expect {
37
+ klass.new([],options)
38
+ }.to raise_error(ArgumentError)
39
+ end
40
+ it "raises an error when photo response object specified" do
41
+ expect {
42
+ klass.new(fixtures.photo,options)
43
+ }.to raise_error(ArgumentError)
44
+ end
45
+
46
+ end
47
+
48
+ context "options hash argument" do
49
+ it "returns object of proper class when all options specified" do
50
+ klass.new(fixtures.photos,{:search_terms => 'shiraz,iran',
51
+ :page => 1,:date => '2010-09-10'}).class.should == klass
52
+ end
53
+ it "returns object of proper class when date is nil" do
54
+ klass.new(fixtures.photos,{:search_terms => 'shiraz,iran',:page => 1,:date => nil}).class.should == klass
55
+ end
56
+ it "raises an error when date is a Fixnum" do
57
+ expect {
58
+ klass.new(fixtures.photos,{:date => 222})
59
+ }.to raise_error(ArgumentError)
60
+ end
61
+ it "raises an error when date is invalid string" do
62
+ expect {
63
+ klass.new(fixtures.photos,{:date => '2010'})
64
+ }.to raise_error(ArgumentError)
65
+ end
66
+ it "raises an error when search_terms is an integer" do
67
+ expect {
68
+ klass.new(fixtures.photos,{:search_terms => 22})
69
+ }.to raise_error(ArgumentError)
70
+ end
71
+ end
72
+ end
73
+
74
+ context "instance methods" do
75
+ specify {subject.should respond_to(:search_terms)}
76
+ context "#search_terms" do
77
+ let(:search_terms){'shiraz,iran'}
78
+ subject {klass.new(fixtures.photos,{:search_terms => search_terms})}
79
+
80
+ it "returns expected has of search_terms" do
81
+ subject.search_terms.should == search_terms
82
+ end
83
+
84
+ it "returns empty string when no search_terms supplied during initialization" do
85
+ klass.new(fixtures.photos,{}).search_terms.should be_empty
86
+ end
87
+ end
88
+
89
+
90
+ specify {subject.should respond_to(:page)}
91
+ context "#page" do
92
+ let(:page) {20}
93
+ subject {klass.new(fixtures.photos,{:page => page})}
94
+ it "returns expected page number when specified at initialization" do
95
+ subject.page.should == page
96
+ end
97
+ it "returns 1 if no page specified at initialization" do
98
+ klass.new(fixtures.photos,{}).page.should == 1
99
+ end
100
+ end
101
+
102
+ specify {subject.should respond_to(:date)}
103
+ context "#date" do
104
+ let(:date) {'2010-09-10'}
105
+ subject {klass.new(fixtures.photos,{:date => date})}
106
+ it "returns expected date" do
107
+ subject.date.should == date
108
+ end
109
+ it "returns nil when called on object with no :date specified" do
110
+ klass.new(fixtures.photos,{}).date.should be_nil
111
+ end
112
+ end
113
+
114
+ specify {subject.should respond_to(:total_results)}
115
+ context "#total_results" do
116
+ it "returns same value as #total_entries" do
117
+ subject.total_results.should == subject.total_entries
118
+ end
119
+ end
120
+
121
+ specify {subject.should respond_to(:capped_entries)}
122
+ context "#capped_entries" do
123
+ it "returns same as total_entries when <= max_entries" do
124
+ subject.photos.stub(:total_entries).and_return(subject.photos.max_entries() -1)
125
+ subject.capped_entries.should == subject.photos.capped_entries
126
+ end
127
+ it "returns max_entries when total_entries > max_entries" do
128
+ subject.photos.stub(:total_entries).and_return(subject.photos.max_entries()+1)
129
+ subject.capped_entries.should == subject.photos.capped_entries
130
+ end
131
+ end
132
+
133
+
134
+ specify{subject.should respond_to(:url_params)}
135
+ context "url_params" do
136
+ it "returns expected parameters when all options specified" do
137
+ options = {:date => '2010-12-20', :search_terms => 'iran,shiraz'}
138
+ klass.new(fixtures.photos,options).url_params.should == options
139
+ end
140
+ it "returns only search_terms when only search_terms is specified" do
141
+ options = {:date => nil, :search_terms => 'iran,shiraz'}
142
+ klass.new(fixtures.photos,options).url_params.should == {:search_terms => 'iran,shiraz'}
143
+ end
144
+ it "returns yesterday for date when no options are specified" do
145
+ options = {:date => nil, :search_terms => nil}
146
+ klass.new(fixtures.photos,options).url_params.should == {:date => APP::Api.time}
147
+ end
148
+ it "returns date when valid date and no search terms is provided" do
149
+ options = {:date => '2010-01-01', :search_terms => nil}
150
+ klass.new(fixtures.photos,options).url_params.should == {:date => '2010-01-01'}
151
+ end
152
+ end
153
+
154
+ specify {subject.should respond_to(:==)}
155
+ context "#==" do
156
+ it "returns true when object is compared to itself" do
157
+ subject.should == subject
158
+ end
159
+ it "returns true when object is compared to clone of itself" do
160
+ subject.should == subject.clone
161
+ end
162
+ it "returns false when object compared to an Array" do
163
+ subject.should_not == []
164
+ end
165
+ it "returns false when object is compared to an object with a single difference" do
166
+ other = subject.clone
167
+ other.photos.last.instance_eval('@delegated_to_object').instance_eval('@h["server"]="1234321"')
168
+ subject.should_not == other
169
+ end
170
+ end
171
+
172
+ context "methods delegated to other object" do
173
+ context "methods delegated to photos object" do
174
+ it "returns identical results as direct call to photos object" do
175
+ klass.delegated_instance_methods.each do |method|
176
+ subject.send(method).should == subject.photos.send(method)
177
+ end
178
+ end
179
+ end
180
+
181
+ specify {subject.should respond_to(:collection)}
182
+ context "#collection" do
183
+ context "usable photos set to nil" do
184
+ let(:reference){
185
+ OpenStruct.new :current_page => subject.current_page,
186
+ :per_page => subject.per_page,
187
+ :total_entries => subject.capped_entries,
188
+ :collection => subject.photos
189
+ }
190
+ it_behaves_like "object that responds to collection"
191
+ end
192
+
193
+ context "usable photos set to true" do
194
+ subject { klass.new fixtures.interesting_photos,options }
195
+ let(:collection){subject.photos.clone.keep_if do |p| p.license.to_i > 3 end}
196
+ let(:reference) {
197
+ OpenStruct.new :current_page => 1,
198
+ :per_page => subject.perpage,
199
+ :total_entries => collection.length,
200
+ :collection => collection
201
+ }
202
+ it_behaves_like "object that responds to collection with usable option"
203
+ end
204
+
205
+ end
206
+
207
+
208
+ context "array accessor methods" do
209
+ let(:reference){subject.photos}
210
+ it_behaves_like "object with delegated Array accessor helpers"
211
+ end
212
+ end
213
+ end
214
+
215
+
216
+ context "metaprogramming methods" do
217
+ specify {subject.should respond_to(:methods)}
218
+ context "#methods" do
219
+ it "return complete list that including the delegated_instance_methods" do
220
+ subject.methods.sort.should == (subject.old_methods +
221
+ subject.delegated_instance_methods).sort
222
+ end
223
+ end
224
+
225
+ specify {subject.should respond_to(:respond_to?)}
226
+ context "respond_to?" do
227
+ it "return true for all methods returned by #methods" do
228
+ subject.methods.each do |method|
229
+ subject.should respond_to(method)
230
+ end
231
+ end
232
+ end
233
+
234
+ specify {subject.should respond_to(:delegated_instance_methods)}
235
+ context "#delegated_instance_methods" do
236
+ it "returns array accessor methods as well as other methods delegated to photos" do
237
+ subject.delegated_instance_methods.sort.should == (FlickrMocks::PhotoSearch.delegated_instance_methods +
238
+ FlickrMocks::Models::Helpers.array_accessor_methods).sort
239
+ end
240
+ end
241
+ end
242
+
243
+
244
+ context "custom cloning methods" do
245
+ context "initialization" do
246
+ it "returns photos with independent indices" do
247
+ other = subject.clone
248
+ subject.photos.each_index do |index|
249
+ subject.photos[index].__id__.should_not == other.photos[index].__id__
250
+ end
251
+ end
252
+ end
253
+ end
254
+
255
+ end