flickrmocks 0.8.15 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
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