flickrmocks 0.8.15 → 0.9.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.
Files changed (53) hide show
  1. data/.gitignore +3 -0
  2. data/Gemfile.lock +123 -0
  3. data/README.rdoc +104 -30
  4. data/Rakefile +12 -0
  5. data/flickrmocks.gemspec +3 -1
  6. data/lib/flickr_mocks/api/api.rb +80 -27
  7. data/lib/flickr_mocks/api/flickr.rb +69 -23
  8. data/lib/flickr_mocks/api/helpers.rb +25 -12
  9. data/lib/flickr_mocks/api/options.rb +71 -53
  10. data/lib/flickr_mocks/api/sanitize.rb +129 -20
  11. data/lib/flickr_mocks/fixtures.rb +7 -1
  12. data/lib/flickr_mocks/flickraw/custom_clone.rb +3 -1
  13. data/lib/flickr_mocks/flickraw/custom_compare.rb +4 -0
  14. data/lib/flickr_mocks/flickraw/custom_marshal.rb +7 -2
  15. data/lib/flickr_mocks/flickraw/flickraw.rb +6 -0
  16. data/lib/flickr_mocks/helpers.rb +8 -1
  17. data/lib/flickr_mocks/models/commons_institution.rb +45 -34
  18. data/lib/flickr_mocks/models/commons_institutions.rb +85 -75
  19. data/lib/flickr_mocks/models/helpers.rb +13 -6
  20. data/lib/flickr_mocks/models/models.rb +7 -0
  21. data/lib/flickr_mocks/models/photo.rb +76 -75
  22. data/lib/flickr_mocks/models/photo_details.rb +71 -69
  23. data/lib/flickr_mocks/models/photo_dimensions.rb +80 -78
  24. data/lib/flickr_mocks/models/photo_search.rb +115 -88
  25. data/lib/flickr_mocks/models/photo_size.rb +57 -56
  26. data/lib/flickr_mocks/models/photo_sizes.rb +68 -67
  27. data/lib/flickr_mocks/models/photos.rb +104 -99
  28. data/lib/flickr_mocks/stubs.rb +151 -14
  29. data/lib/flickr_mocks/version.rb +7 -1
  30. data/spec/api/api_spec.rb +26 -8
  31. data/spec/api/flickr_spec.rb +19 -19
  32. data/spec/api/helper_spec.rb +20 -20
  33. data/spec/api/options_spec.rb +170 -124
  34. data/spec/api/sanitize_spec.rb +174 -59
  35. data/spec/base/stubs_spec.rb +37 -74
  36. data/spec/base/version_spec.rb +11 -4
  37. data/spec/models/commons_institution_spec.rb +3 -2
  38. data/spec/models/commons_institutions_spec.rb +34 -5
  39. data/spec/models/helpers_spec.rb +7 -6
  40. data/spec/models/photo_details_spec.rb +12 -11
  41. data/spec/models/photo_dimensions_spec.rb +5 -4
  42. data/spec/models/photo_search_spec.rb +50 -8
  43. data/spec/models/photo_size_spec.rb +4 -3
  44. data/spec/models/photo_sizes_spec.rb +6 -5
  45. data/spec/models/photo_spec.rb +6 -4
  46. data/spec/models/photos_spec.rb +9 -7
  47. data/spec/shared_examples/hash_options/date_hash_option.rb +42 -0
  48. data/spec/shared_examples/hash_options/page_hash_option.rb +23 -0
  49. data/spec/shared_examples/hash_options/perpage_hash_option.rb +43 -0
  50. data/spec/shared_examples/hash_options/tag_mode_hash_option.rb +31 -0
  51. data/spec/shared_examples/stub_helpers.rb +140 -0
  52. data/spec/spec_helper.rb +5 -5
  53. metadata +55 -16
@@ -1,62 +1,80 @@
1
1
  module FlickrMocks
2
2
  class Api
3
- def self.search_options(params)
4
- return {
5
- :tags => self.sanitize_tags(params[:search_terms]),
6
- :user_id => params[:owner_id],
7
- :per_page => self.sanitize_per_page(params),
8
- :page => self.sanitize_page(params),
9
- :license => self.default(:license),
10
- :media => self.default(:media),
11
- :extras => self.default(:extras),
12
- :tag_mode => self.sanitize_tag_mode(params)
13
- }
14
- end
3
+ # encapsulates methods that extract options from user-specified hash. Module is
4
+ # used internally.
5
+ module Options
6
+ # returns parameter hash required for a flickr photo search. Sample usage:
7
+ #
8
+ # self.search(:search_terms => 'iran', :tag_mode => 'any')
9
+ #
10
+ # Accepted options include:
11
+ # :search_terms : comma string containing the flickr search tags. Sample string 'lyon,france"
12
+ # :owner_id : id for the photo. (either :owner_id or :search_terms must be specified
13
+ # :per_page : optional string containing the maximum number of items to return for a given page
14
+ # :page : optional string containing page number for the results. When page number is <= 0, it returns 1.
15
+ # :tag_mode : optional string containing how the tags for :search_terms should be interpreted. Can be either 'any' or 'all'
16
+ def self.search(params)
17
+ return {
18
+ :tags => Api::Sanitize.tags(params[:search_terms]),
19
+ :user_id => params[:owner_id],
20
+ :per_page => Api::Sanitize.per_page_hash(params),
21
+ :page => Api::Sanitize.page_hash(params),
22
+ :license => Api.default(:license),
23
+ :media => Api.default(:media),
24
+ :extras => Api.default(:extras),
25
+ :tag_mode => Api::Sanitize.tag_mode_hash(params)
26
+ }
27
+ end
15
28
 
16
- def self.interesting_options(params)
17
- return {
18
- :date => self.sanitize_time(params),
19
- :per_page => self.sanitize_per_page(params),
20
- :page => self.sanitize_page(params),
21
- :extras => self.default(:extras)
22
- }
23
- end
29
+
30
+ # returns parameter hash that is supplied for a interesting photo search. Sample usage:
31
+ #
32
+ # self.interesting(:date => '2010-10-10')
33
+ #
34
+ # Accepted options include:
35
+ # :date : string of format 'YYYY-MM-DD'. Photos of this date are retrieved. If none supplied, yesterday's date is used.
36
+ # :per_page : optional string containing the maximum number of items to return for a given page
37
+ # :page : optional string containing page number for the results. When page number is <= 0, it returns 1.
38
+ #
39
+ def self.interesting(params)
40
+ return {
41
+ :date => Api::Sanitize.date_hash(params),
42
+ :per_page => Api::Sanitize.per_page_hash(params),
43
+ :page => Api::Sanitize.page_hash(params),
44
+ :extras => Api.default(:extras)
45
+ }
46
+ end
24
47
 
25
- def self.photo_options(params)
26
- {
27
- :photo_id => params[:photo_id] || params[:id] || nil,
28
- :secret => params[:photo_secret] || params[:secret] || nil
29
- }
30
- end
31
-
32
- def self.author_options(params)
33
- options = self.search_options(params)
34
- options.delete :tags
35
- options
36
- end
37
-
38
- def self.search_params(params)
39
- return {
40
- :search_terms => self.sanitize_tags(params[:search_terms]),
41
- :owner_id => self.sanitize_tags(params[:owner_id]),
42
- :base_url => params[:base_url]
43
- }
44
- end
45
-
46
- def self.interesting_params(params)
47
- return {
48
- :date => params[:date],
49
- :base_url => params[:base_url]
50
- }
51
- end
48
+ # returns parameter hash for a single photo. Sample usage:
49
+ #
50
+ # self.photo(:photo_id => '123')
51
+ #
52
+ # Accepted options include:
53
+ # :photo_id : string containing photo_id of the photo.
54
+ # :id : string containing photo id of the photo. It is an alias for :photo_id. If both are present :photo_id takes precedance.
55
+ # :secret : optional string containing the secret for the photo. If supplied the query is slightly faster.
56
+ # :photo_secret : optional string containing the secret for the photo. It is an alias for :secret. If both supplied, :secret takes precedance.
57
+ def self.photo(params)
58
+ {
59
+ :photo_id => params[:photo_id] || params[:id] || nil,
60
+ :secret => params[:photo_secret] || params[:secret] || nil
61
+ }
62
+ end
52
63
 
53
- def self.commons_institutions_params(params)
54
- return {
55
- :per_page => params[:per_page] || params[:perpage],
56
- :current_page => params[:current_page] || params[:page] || 1
57
- }
64
+ # returns parameter hash used for searching for photos of a given author. Sample usage:
65
+ #
66
+ # self.search(:owner_id => '1234')
67
+ #
68
+ # Accepted options include:
69
+ # :owner_id : id for the photo. (either :owner_id or :search_terms must be specified
70
+ # :per_page : optional string containing the maximum number of items to return for a given page
71
+ # :page : optional string containing page number for the results. When page number is <= 0, it returns 1.
72
+ def self.author(params)
73
+ options = Api::Options.search(params)
74
+ options.delete :tags
75
+ options
76
+ end
58
77
  end
59
78
  end
60
79
 
61
-
62
80
  end
@@ -1,29 +1,138 @@
1
1
  module FlickrMocks
2
2
  class Api
3
- def self.sanitize_tags(value=nil)
4
- value.nil? ? value : value.downcase.split(',').map.each do |v| v.strip end.join(',')
5
- end
3
+ # helper methods that help to clean up user supplied values. Module is
4
+ # used internally.
5
+ module Sanitize
6
+ # returns a lowercase stripped version of the supplied comma separated string. Sample usage:
7
+ #
8
+ # Api.sanitize_tags('Shiraz , HeLLo goodbye, wow')
9
+ # returns 'shiraz,hello goodbye,wow'
10
+ def self.tags(value=nil)
11
+ case value
12
+ when nil then
13
+ nil
14
+ when String then
15
+ value.downcase.split(',').map.each do |v| v.strip end.join(',')
16
+ else
17
+ raise ArgumentError
18
+ end
19
+ end
6
20
 
7
- def self.sanitize_per_page(params={})
8
- params[:per_page] || params[:perpage] || self.default(:per_page)
9
- end
21
+ # returns lowercase stripped version of the supplied string stored in the :search_terms key of the
22
+ # supplied hash. Sample usage:
23
+ #
24
+ # self.sanitize_tags(:search_terms => 'Shiraz , HeLLo goodbye, wow')
25
+ # returns 'shiraz,hello goodbye,wow'
26
+ def self.tags_hash(options={})
27
+ raise ArgumentError unless options.is_a?(Hash)
28
+ self.tags(options[:search_terms])
29
+ end
10
30
 
11
- def self.sanitize_page(params={})
12
- [nil,0,'0'].include?(params[:page]) ? '1' : params[:page].to_i.to_s
13
- end
31
+ # returns the per page entry if supplied otherwise returns the default per page value.
32
+ # Sample usage:
33
+ #
34
+ # self.per_page('10')
35
+ # returns '10'
36
+ def self.per_page(value=nil)
37
+ case value
38
+ when String then
39
+ value.to_i > 0 ? value.to_i.to_s : Api.default(:per_page)
40
+ when Fixnum then
41
+ value > 0 ? value.to_i.to_s : Api.default(:per_page)
42
+ when nil then
43
+ Api.default(:per_page)
44
+ else
45
+ raise ArgumentError
46
+ end
47
+ end
14
48
 
15
- def self.sanitize_tag_mode(params={})
16
- self.default(:flickr_tag_modes).include?(params[:tag_mode].to_s.downcase.strip) ?
17
- params[:tag_mode].to_s.downcase.strip : self.default(:tag_mode)
18
- end
49
+ # returns the per page entry stored in the :per_page key of the supplied options hash.
50
+ # Sample usage:
51
+ #
52
+ # self.per_page_hash(:per_page => '10')
53
+ # returns '10'
54
+ def self.per_page_hash(options={})
55
+ if options[:per_page]
56
+ self.per_page(options[:per_page])
57
+ elsif options[:perpage]
58
+ self.per_page(options[:perpage])
59
+ else
60
+ self.per_page(nil)
61
+ end
62
+ end
63
+
64
+ # returns the page number. Ensures that return value is string containing an integer
65
+ # greater than 0. When nonsensical page supplied, default page '1' is returned. Sample usage:
66
+ #
67
+ # self.page('20')
68
+ # returns '20'
69
+ def self.page(value={})
70
+ case value
71
+ when Fixnum then
72
+ value > 0 ? value.to_s : Api.default(:page)
73
+ when NilClass then
74
+ Api.default(:page)
75
+ when String
76
+ value.to_i > 0 ? value.to_i.to_s : Api.default(:page)
77
+ else
78
+ raise ArgumentError
79
+ end
80
+ end
81
+
82
+ # returns the page number contained in the :page key of the supplied hash. Sample usage:
83
+ #
84
+ # self.page(:page => '20')
85
+ # returns '20'
86
+ def self.page_hash(options={})
87
+ self.page(options[:page])
88
+ end
89
+
90
+ # returns tag mode. It ensures that a valid tag mode is returned. If an invalid
91
+ # tag_mode is supplied it returns the default tag mode 'all'. Sample usage:
92
+ #
93
+ # self.tag_mode('any')
94
+ # returns 'any'
95
+ def self.tag_mode(value=nil)
96
+ case value
97
+ when String then
98
+ Api.default(:possible_tag_modes).include?(value.to_s.downcase) ?
99
+ value.to_s.downcase : Api.default(:tag_mode)
100
+ when nil then
101
+ Api.default(:tag_mode)
102
+ else
103
+ raise ArgumentError
104
+ end
105
+ end
106
+
107
+ # returns tag_mode contained in the :tag_mode key of the supplied hash. Sample usage:
108
+ #
109
+ # self.tag_mode(:tag_mode => 'any')
110
+ # returns 'any'
111
+ def self.tag_mode_hash(options={})
112
+ self.tag_mode(options[:tag_mode].to_s.downcase.strip)
113
+ end
114
+
115
+ # returns a string of format YYYY-MM-DD. Accepts either a Time object or a string as
116
+ # an argument. If invalid date supplied the string corresponding to yesterday's date is returned.
117
+ # Sample usage:
118
+ # self.date('2010-10-10')
119
+ # returns => '2010-10-10'
120
+ def self.date(value=nil)
121
+ case value
122
+ when String then Api::Helpers.date(value)
123
+ when Time then value.strftime('%Y-%m-%d')
124
+ else Api::Helpers.date('yesterday')
125
+ end
126
+ end
19
127
 
20
- def self.sanitize_time(params={})
21
- date = params[:date]
22
- case date
23
- when Time then date.strftime('%Y-%m-%d')
24
- when String then self.time(date)
25
- else self.time('yesterday')
128
+ # returns string of format YYYY-MM-DD corresponding to the value stored in the :date
129
+ # key of the options hash. Sample usage:
130
+ #
131
+ # self.date_hash(:date => '2010-10-10')
132
+ # returns '2010-10-10'
133
+ def self.date_hash(options={})
134
+ self.date(options[:date])
26
135
  end
27
136
  end
28
137
  end
29
- end
138
+ end
@@ -2,6 +2,12 @@ require 'ostruct'
2
2
  require 'singleton'
3
3
 
4
4
  module FlickrMocks
5
+ # contains fixtures for various FlickRaw responses. This class is used internally.
6
+ # For stubbing FlickrRaw APIs for your Rspec 2.0 please refer to the
7
+ # FlickrMocks::Stubs class. This is a singleton class. To access the singleton
8
+ # class instance you can call:
9
+ #
10
+ # Fixtures.instance
5
11
  class Fixtures
6
12
  include Singleton
7
13
  attr_accessor :photos,:interesting_photos,:author_photos,:photo,:photo_details,
@@ -25,9 +31,9 @@ module FlickrMocks
25
31
  @empty_photos = load_fixture(:empty_photos)
26
32
 
27
33
  @expected_methods = load_fixture(:expected_methods)
28
-
29
34
  end
30
35
 
36
+ # returns directory where fixtures are stored.
31
37
  def self.repository
32
38
  File.expand_path(File.dirname(__FILE__) + '/../../spec/fixtures') + '/'
33
39
  end
@@ -1,7 +1,9 @@
1
1
  module FlickrMocks
2
2
 
3
+ # module is included in classes that wrap the FlickRaw::Response and FlickRaw::ResponseList
4
+ # objects. Module is used internally.
3
5
  module CustomClone
4
-
6
+ # special ruby method that overrides Ruby's cloning method.
5
7
  def initialize_copy(orig)
6
8
  super
7
9
  cloned = @h.clone
@@ -1,6 +1,10 @@
1
1
  module FlickrMocks
2
2
 
3
+ # module that contains methods that contain custom '==' check. This module is
4
+ # used internally and is included in the FlickrMocks::Models.
3
5
  module CustomCompare
6
+ # custom equality method that is added in various classes to override Ruby's default
7
+ # '==' behavior
4
8
  def ==(other)
5
9
  return false if other.nil?
6
10
  return false unless other.is_a?(self.class)
@@ -1,12 +1,16 @@
1
1
  module FlickrMocks
2
2
 
3
+ # contains custom methods that allow the marshaling of FlickRaw::Response and
4
+ # FlickRaw::ResponseList objects. FlickRaw responses contain singleton methods that
5
+ # can not be marshaled by default. This module is used internally
3
6
  module CustomMarshal
4
7
 
5
- def self.included(base)
8
+ def self.included(base)
6
9
  base.extend ClassMethods
7
10
  end
8
11
 
9
- module ClassMethods
12
+ module ClassMethods
13
+ # used to un-marshal FlickRaw responses
10
14
  def _load(string)
11
15
  data = Marshal.load(string)
12
16
  type = data.delete('flickr_type')
@@ -14,6 +18,7 @@ module FlickrMocks
14
18
  end
15
19
  end
16
20
 
21
+ # used to marshal FlickRaw responses
17
22
  def _dump(level)
18
23
  result = marshal_flickraw(self)
19
24
  result["flickr_type"] = self.flickr_type
@@ -1,11 +1,17 @@
1
+
2
+ # adds custom cloning, marshaling and compare methods to the FlickRaw::Response
3
+ # and FlickRaw::ResponseList class. These additional methods help in testing
4
+ # the FlickrMocks models.
1
5
  module FlickRaw
2
6
 
7
+ # adds custom cloning, marshaling and compare methods to FlickRaw::Response class
3
8
  class Response
4
9
  include FlickrMocks::CustomMarshal
5
10
  include FlickrMocks::CustomCompare
6
11
  include FlickrMocks::CustomClone
7
12
  end
8
13
 
14
+ # adds custom cloning, marshaling and compare methods to FlickRaw::ResponseList class
9
15
  class ResponseList
10
16
  include FlickrMocks::CustomMarshal
11
17
  include FlickrMocks::CustomCompare
@@ -1,16 +1,21 @@
1
1
  module FlickrMocks
2
+ # contains various helper methods for comparing and marshaling FlickRaw::Response and
3
+ # ResponseList objects.
2
4
  module Helpers
3
-
4
5
  class << self
6
+ # returns the file extension used to store the marshaled FlickRaw fixtures
5
7
  def extension
6
8
  ".marshal"
7
9
  end
8
10
 
11
+ # returns the file name for the marshaled FlickRaw fixture
9
12
  def fname_fixture(symbol)
10
13
  raise RunTimeError unless symbol.is_a? Symbol
11
14
  symbol.to_s + extension
12
15
  end
13
16
 
17
+ # compares two FlickRaw::Response or two FlickRaw::ResponseList.
18
+ # It recursively checks the internal state of these two objects.
14
19
  def equivalent?(a,b)
15
20
  return false if a.class != b.class
16
21
  case a
@@ -30,6 +35,7 @@ module FlickrMocks
30
35
  end
31
36
  end
32
37
 
38
+ # saves the marshaled version of the supplied object into a file
33
39
  def dump(response,file)
34
40
  begin
35
41
  f = File.open(file,'w')
@@ -39,6 +45,7 @@ module FlickrMocks
39
45
  end
40
46
  end
41
47
 
48
+ # returns the un-marshaled contents of the user-specified file
42
49
  def load(file)
43
50
  begin
44
51
  f=File.open(file,'r')
@@ -1,45 +1,55 @@
1
1
 
2
2
  module FlickrMocks
3
- class CommonsInstitution
4
- def initialize(object)
5
- self.delegated_to_object = object
6
- end
7
-
8
- def launch_date
9
- @delegated_to_object.date_launch
10
- end
3
+ module Models
4
+ class CommonsInstitution
5
+ def initialize(object)
6
+ self.delegated_to_object = object
7
+ end
11
8
 
12
- def owner_id
13
- @delegated_to_object.nsid
14
- end
15
- alias :owner :owner_id
9
+ # returns the launch date for the commons institution
10
+ def launch_date
11
+ @delegated_to_object.date_launch
12
+ end
16
13
 
17
- def owner_name
18
- @delegated_to_object.name
19
- end
14
+ # returns the Owner id for the commons institution
15
+ def owner_id
16
+ @delegated_to_object.nsid
17
+ end
18
+ alias :owner :owner_id
20
19
 
21
- def flickr_url
22
- get_url(:flickr)
23
- end
20
+ # returns name of the commons institution
21
+ def owner_name
22
+ @delegated_to_object.name
23
+ end
24
24
 
25
- def site_url
26
- get_url(:site)
27
- end
28
-
29
- def license_url
30
- get_url(:license)
31
- end
25
+ # returns flickr web address for the institution
26
+ def flickr_url
27
+ get_url(:flickr)
28
+ end
32
29
 
33
- def ==(other)
34
- @delegated_to_object == other.instance_eval('@delegated_to_object')
35
- end
30
+ # returns external web address for the institution
31
+ def site_url
32
+ get_url(:site)
33
+ end
36
34
 
37
- def initialize_copy(orig)
38
- super
39
- @delegated_to_object = @delegated_to_object.clone
40
- end
41
-
42
- private
35
+ # returns the url that describes the licensing
36
+ def license_url
37
+ get_url(:license)
38
+ end
39
+
40
+ # returns true if supplied object is equivalent to self
41
+ def ==(other)
42
+ @delegated_to_object == other.instance_eval('@delegated_to_object')
43
+ end
44
+
45
+ # customizes the cloning behavior of the object. Internal state of cloned object
46
+ # will not point to original object.
47
+ def initialize_copy(orig)
48
+ super
49
+ @delegated_to_object = @delegated_to_object.clone
50
+ end
51
+
52
+ private
43
53
  def delegated_to_object=(object)
44
54
  raise ArgumentError, "Expected object of class FlickRaw::Response but received #{object.class}" unless object.class == FlickRaw::Response
45
55
  @delegated_to_object = object
@@ -52,5 +62,6 @@ module FlickrMocks
52
62
  def get_url_index(type)
53
63
  @delegated_to_object.urls.map do |url| url['type'].to_sym end.find_index(type.to_sym)
54
64
  end
65
+ end
55
66
  end
56
67
  end