starwars 0.0.1 → 0.0.2

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 (38) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +1 -1
  3. data/.travis.yml +1 -0
  4. data/README.md +63 -19
  5. data/lib/starwars.rb +16 -7
  6. data/lib/starwars/base.rb +129 -25
  7. data/lib/starwars/cursor.rb +110 -0
  8. data/lib/starwars/error.rb +63 -0
  9. data/lib/starwars/overrides/ostruct.rb +16 -0
  10. data/lib/starwars/request.rb +80 -0
  11. data/lib/starwars/resources/film.rb +79 -0
  12. data/lib/starwars/resources/paginated/films.rb +8 -0
  13. data/lib/starwars/resources/paginated/people.rb +8 -0
  14. data/lib/starwars/resources/paginated/planets.rb +9 -0
  15. data/lib/starwars/resources/paginated/species.rb +8 -0
  16. data/lib/starwars/resources/paginated/starships.rb +8 -0
  17. data/lib/starwars/resources/paginated/vehicles.rb +8 -0
  18. data/lib/starwars/resources/person.rb +124 -0
  19. data/lib/starwars/{planet.rb → resources/planet.rb} +0 -13
  20. data/lib/starwars/{specie.rb → resources/specie.rb} +1 -15
  21. data/lib/starwars/resources/starship.rb +115 -0
  22. data/lib/starwars/resources/vehicle.rb +106 -0
  23. data/lib/starwars/version.rb +1 -1
  24. data/spec/fixtures/404.json +1 -0
  25. data/spec/fixtures/planets_page1.json +1 -0
  26. data/spec/fixtures/planets_page2.json +1 -0
  27. data/spec/starwars/base_spec.rb +17 -0
  28. data/spec/starwars/cursor_spec.rb +76 -0
  29. data/spec/starwars/person_spec.rb +1 -1
  30. data/spec/starwars/request_spec.rb +29 -0
  31. data/spec/starwars/resources/paginated/planets_spec.rb +38 -0
  32. data/starwars.gemspec +0 -1
  33. metadata +32 -23
  34. data/lib/starwars/fetcher.rb +0 -40
  35. data/lib/starwars/film.rb +0 -35
  36. data/lib/starwars/person.rb +0 -39
  37. data/lib/starwars/starship.rb +0 -40
  38. data/lib/starwars/vehicle.rb +0 -38
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ad657666a52a78f6326d5781ee9f1c12f19e5b54
4
- data.tar.gz: 07fefe6fd93d76fb5bf6184093608379a7252147
3
+ metadata.gz: 8b3c2a3fcfdfe161e04b8f4e5680513ce45fb5ed
4
+ data.tar.gz: 2c0a63b841991f163d15156d2f42ec1644eb7320
5
5
  SHA512:
6
- metadata.gz: 6b9c5802184691e8e1337a9048488e5b2d0fd8d258c799e9526fc065c7456d1f3bfff9a3ccc83a3a05d8978007ea55d661fae4f38f75dc91b8d36589034ce952
7
- data.tar.gz: bda6c580a84b436c3eb057ee174de48f3253556eb13f227c140d5d92c23c60f09ced5d58088b97640ee233bbd3d1367714dbe7bfd04718a104c2557ec9a9d279
6
+ metadata.gz: 438b2c0f53551ed7bf5ee790bbe2bd052282f5838636ff4e4b1ec9c47c167f9ca9db11bfbddb9291eb520b7383bf52e4ea8f6a93ea0fa9be35a9a017199c15b6
7
+ data.tar.gz: 6638b91db1386184b23ed1f29d9841f3d2f177738126d289c496028560bdd6714ea70f7c4d5775e9c7a1adf9a0b5d8f0736970e2ab89512cb7256bdfb3dd1d50
@@ -1,2 +1,2 @@
1
1
  Metrics/LineLength:
2
- Max: 140
2
+ Max: 160
@@ -19,6 +19,7 @@ matrix:
19
19
  - rvm: jruby-20mode
20
20
  - rvm: jruby-21mode
21
21
  - rvm: rbx-2
22
+ - rvm: jruby-19mode
22
23
  fast_finish: true
23
24
  branches:
24
25
  only: master
data/README.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # Starwars
2
2
 
3
+ [![Coverage Status](https://coveralls.io/repos/moski/starwars/badge.png?branch=master)](https://coveralls.io/r/moski/starwars?branch=master)
4
+ [![Build Status](https://travis-ci.org/moski/starwars.svg?branch=master)](https://travis-ci.org/moski/starwars)
5
+ [![Inline docs](http://inch-ci.org/github/moski/starwars.svg?branch=master&style=flat)](http://inch-ci.org/github/moski/starwars)
6
+
3
7
  A Ruby interface for http://swapi.co/ - the Star Wars API
4
8
  ![Starwars](https://s3.amazonaws.com/f.cl.ly/items/1r2F2K460v1R2o011n1M/star-wars-evolution-evolution-funny.jpg)
5
9
 
@@ -26,29 +30,69 @@ Or install it yourself as:
26
30
 
27
31
  $ gem install starwars
28
32
 
33
+
34
+ ## Available Resources
35
+
36
+ * `Starwars::Person` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/person.rb))
37
+ * `Starwars::Film` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/film.rb))
38
+ * `Starwars::Planet` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/planet.rb))
39
+ * `Starwars::Specie` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/specie.rb))
40
+ * `Starwars::Starship` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/starship.rb))
41
+ * `Starwars::Vehicle` ([see docs](https://github.com/moski/starwars/blob/master/lib/starwars/resources/vehicle.rb))
42
+
29
43
  ## Usage
30
- require "starwars"
31
- luke = Starwars::Person.fetch(1)
32
- puts luke.name
33
- puts luke.height
34
44
 
35
- falcon = Starwars::Spaceship.new(id: 10)
36
- falcon.fetch
37
- puts falcon.name
38
- puts falcon.pilots
45
+ All the resources defined above have 2 functions, `#fetch` and `#fetch_all`
46
+
47
+ ## #Fetch
48
+
49
+ `#fetch` is used to fetch a single resource via ID or Resource URL
50
+
51
+ ```ruby
52
+ Starwars::Person.fetch(1).name
53
+ Starwars::Person.fetch('http://swapi.co/api/people/3/').name
54
+ ```
55
+
56
+ ## #fetch_all
57
+
58
+ `#fetch_all` is used to fetch all resources via pagination
59
+
60
+ ```ruby
61
+ planets = Starwars::Planet.fetch_all
62
+
63
+ # to access the items use #items
64
+ planets.items.map(&:name)
65
+ planets.items.each{|item| p item.inspect}
66
+
67
+ # you can also use #results instead of iteams
68
+ planets.results.map(&:name)
69
+ ```
70
+
71
+ ## Pagination
72
+
73
+ using `#fetch_all` will yield a pagination response:
74
+
75
+ ```ruby
76
+ starships = Starwars::Starship.fetch_all
77
+ p starships.number_of_pages
78
+ p starships.last_page?
79
+ p starships.next_page?
80
+ ```
81
+
82
+ To iterate pages you can use the following interface:
83
+
84
+ ```ruby
85
+ Starwars::Starship.fetch_all.each{|page|
86
+ p page.next
87
+ p page.previous
88
+ p page.results.size
89
+ }
90
+ ```
39
91
 
40
- you can also nest the quries, such as:
41
-
42
- falcon.pilots.each do |piolt|
43
- puts piolt.fetch.name
44
- end
92
+ ## Documentation
45
93
 
46
- You can load a resouce by url:
94
+ the gem is fairly documented. Browse the YARD [documentaion](http://rubydoc.info/gems/starwars/) for more information.
47
95
 
48
- aldeeran = Starwars::Planet.new(url: 'http://swapi.co/api/planets/3/').fetch
49
- puts aldeeran.name
50
- puts aldeeran.residents
51
- puts aldeeran.population
52
96
 
53
97
  ## Contributing
54
98
 
@@ -56,4 +100,4 @@ Or install it yourself as:
56
100
  2. Create your feature branch (`git checkout -b my-new-feature`)
57
101
  3. Commit your changes (`git commit -am 'Add some feature'`)
58
102
  4. Push to the branch (`git push origin my-new-feature`)
59
- 5. Create a new Pull Request
103
+ 5. Create a new Pull Request
@@ -1,6 +1,7 @@
1
1
  require 'starwars/version'
2
2
  require 'starwars/base'
3
- require 'starwars/fetcher'
3
+ require 'starwars/request'
4
+ require 'starwars/cursor'
4
5
 
5
6
  # Avoid circuler require issues :(
6
7
  module Starwars
@@ -11,9 +12,17 @@ module Starwars
11
12
  class Vehicle < Starwars::Base; end
12
13
  class Starship < Starwars::Base; end
13
14
  end
14
- require 'starwars/planet'
15
- require 'starwars/person'
16
- require 'starwars/specie'
17
- require 'starwars/vehicle'
18
- require 'starwars/starship'
19
- require 'starwars/film'
15
+ require 'starwars/resources/planet'
16
+ require 'starwars/resources/person'
17
+ require 'starwars/resources/specie'
18
+ require 'starwars/resources/vehicle'
19
+ require 'starwars/resources/starship'
20
+ require 'starwars/resources/film'
21
+
22
+ # Resources with pagination
23
+ require 'starwars/resources/paginated/planets'
24
+ require 'starwars/resources/paginated/films'
25
+ require 'starwars/resources/paginated/people'
26
+ require 'starwars/resources/paginated/species'
27
+ require 'starwars/resources/paginated/starships'
28
+ require 'starwars/resources/paginated/vehicles'
@@ -1,8 +1,7 @@
1
1
  require 'roar/json'
2
2
  require 'roar/client'
3
3
  require 'roar/coercion'
4
- require 'ostruct'
5
- require 'equalizer'
4
+ require 'starwars/overrides/ostruct'
6
5
  require 'virtus'
7
6
 
8
7
  module Starwars
@@ -10,6 +9,10 @@ module Starwars
10
9
  # Base Class for fetching all the data from the remote api.
11
10
  # All Classes should inhert from this class.
12
11
  #
12
+ # Abstract base class for the different resources.
13
+ # Provides some helper methods for the resources.
14
+ #
15
+ # @abstract
13
16
  class Base < OpenStruct
14
17
  include Roar::JSON
15
18
  include Roar::Client
@@ -18,36 +21,137 @@ module Starwars
18
21
  BASE_URL = 'http://swapi.co/api'
19
22
  FORMAT = 'application/json'
20
23
 
24
+ #
25
+ # Class level methods for resources to fetch data from api
26
+ # @abstract
27
+ class << self
28
+ #
29
+ # Fetch an object by id or URL
30
+ # @param [String, Integer] param String for full resouce url or the resouce id
31
+ # @return [Person, Film, Planet, Specie, Starship, Vehicle]
32
+ # @example Fetch person by id
33
+ # Starwars::Person.fetch(1)
34
+ #
35
+ # @example Fetch person by url
36
+ # Starwars::Person.fetch("http://swapi.co/api/people/2/")
37
+ # @api public
38
+ def fetch(param)
39
+ object = new(url: link(param))
40
+ Starwars::Request.new(object.request_attributes).perform_request
41
+ end
42
+
43
+ #
44
+ # Fetch all resource data page by page
45
+ # @return [People, Films, Planets, Species, Starships, Vehicles]
46
+ # @example Fetch Planets page by page
47
+ # Starwars::Planet.fetch_all.each do |page|
48
+ # puts page.items.size
49
+ # end
50
+ # @api public
51
+ def fetch_all
52
+ klass_name = Starwars.const_get(name.split('::').last).const_get('RESOURCE_NAME')
53
+ object = Starwars.const_get("#{klass_name.capitalize}").new(url: "#{Starwars::Base::BASE_URL}/#{klass_name}/")
54
+ Starwars::Request.new(resource: object, uri: object.url, params: {}).perform_request
55
+ end
56
+
57
+ protected
58
+
59
+ #
60
+ # Generate a resource link based on the passed params
61
+ # @param [String, Integer] param String for full resouce url or the resouce id
62
+ # @return [String] resouce link
63
+ # @api private
64
+ def link(param)
65
+ if param.is_a? String
66
+ param
67
+ else
68
+ "#{Starwars::Base::BASE_URL}/#{const_get('RESOURCE_NAME')}/#{param}/"
69
+ end
70
+ end
71
+ end
72
+
73
+ # The time the resource was created
74
+ # @return [Time]
75
+ # @example
76
+ # film.created
77
+ # @api public
78
+ property :created, type: Time
79
+
80
+ # The time the resource was edited
81
+ # @return [Time]
82
+ # @example
83
+ # film.edited
84
+ # @api public
85
+ property :edited, type: Time
86
+
87
+ # The resource unique id
88
+ # @return [Integer]
89
+ # @example
90
+ # film.id #=> 1
91
+ # @api public
92
+ property :id, type: Integer
93
+
94
+ # The hypermedia URL of this resource
95
+ # @return [String]
96
+ # @example
97
+ # film.url #=> 'http://swapi.co/api/films/1/'
98
+ # @api public
99
+ property :url
100
+
101
+ #
102
+ # Overide the == method for any resource to check the ID and URL
103
+ # @param [People, Films, Planets, Species, Starships, Vehicles] other
104
+ # @return [Boolean]
105
+ # @example If id's and urls are equal
106
+ # Starwars::Planet.new(id: 1, url: "/some") == Starwars::Planet.new(id: 1, url: "/some") #=> true
107
+ # @example If id's and urls are equal
108
+ # Starwars::Planet.new(id: 2, url: "/some") == Starwars::Planet.new(id: 1, url: "/some") #=> false
109
+ # @example If id's and urls are equal
110
+ # Starwars::Planet.new(id: 1, url: "/some1") == Starwars::Planet.new(id: 1, url: "/some") #=> false
111
+ # @api public
21
112
  def ==(other)
22
113
  id == other.id && url == other.url
23
114
  end
24
115
 
25
- def fetch(resource_name)
26
- #
27
- # If the url is set, then fetch using the resource url
28
- #
116
+ #
117
+ # Fetch a resource if the ID or URL is set
118
+ # @return [Person, Film, Planet, Specie, Starship, Vehicle]
119
+ # @example Fetch person by id
120
+ # Starwars::Person.new(id: 1).fetch
121
+ #
122
+ # @example Fetch person by url
123
+ # Starwars::Person.new(url: "http://swapi.co/api/people/2/").fetch
124
+ # @api public
125
+ def fetch
126
+ Starwars::Request.new(request_attributes).perform_request
127
+ end
128
+
129
+ #
130
+ # Generate the Request initialize params
131
+ # @param [Hash] opts the options to create a Request with.
132
+ # @option opts [Person, Film, Planet, Specie, Starship, Vehicle] :resource
133
+ # @option opts [String] :uri resource uri
134
+ # @option opts [Hash] :params other params
135
+ # @return [Hash]
136
+ # @api private
137
+ def request_attributes(opts = {})
138
+ { resource: self, uri: link, params: {} }.merge(opts)
139
+ end
140
+
141
+ protected
142
+
143
+ #
144
+ # Generate a resource link from the URL or id
145
+ # @return [String] resource link
146
+ # @raise [Starwars::Error::ArgumentError] if no id or url
147
+ # @api private
148
+ def link
29
149
  if url
30
- get(uri: url, as: FORMAT)
31
- #
32
- # Try to fetch using the resource name and ID
33
- #
150
+ url
34
151
  elsif id
35
- get(uri: "#{BASE_URL}/#{resource_name}/#{id}/", as: FORMAT)
152
+ "#{Starwars::Base::BASE_URL}/#{self.class::RESOURCE_NAME}/#{id}/"
36
153
  else
37
- fail 'error'
38
- end
39
- end
40
- class << self
41
- def fetch(resources, id)
42
- #
43
- # Special case for person and people, instead of removing the s
44
- #
45
- if (resources == 'people')
46
- resources = 'person'
47
- else
48
- resources.slice!(-1, 1)
49
- end
50
- Starwars.const_get(resources.capitalize).new(id: id).fetch
154
+ fail(Starwars::Error::ArgumentError.new('Please use id or url to fetch resouce', nil))
51
155
  end
52
156
  end
53
157
  end
@@ -0,0 +1,110 @@
1
+ module Starwars
2
+ #
3
+ # A pagination container for starwars
4
+ #
5
+ class Cursor < Starwars::Base
6
+ include Enumerable
7
+
8
+ #
9
+ # including Enumerable adds a "count" method to the class
10
+ # and for some reason:
11
+ # property :count, as: number_of_pages
12
+ # is not working, i am not sure it's a roar thing or from the representable gem.
13
+ # As a workaround, lets create "number_of_pages" method that returns
14
+ # the count property
15
+ # @todo - check why as: is not working
16
+ property :count
17
+
18
+ #
19
+ # Next holds the URL for the next page. If there is no next page, next
20
+ # should be set to nil
21
+ property :next
22
+
23
+ #
24
+ # Previous holds the URL for the previous page. If there is no previous
25
+ # page previous should be set to nil
26
+ property :previous
27
+
28
+ # Results contains the results within the page.
29
+ #
30
+ collection :results
31
+
32
+ # A wrapper to get the pages count from the api
33
+ # @return [Integer]
34
+ # @example get the total number of pages
35
+ # Starwars::Planet.fetch_all.number_of_pages
36
+ # @example get the total number of pages
37
+ # Starwars::Starship.fetch_all.number_of_pages
38
+ # @api public
39
+ def number_of_pages
40
+ self[:count]
41
+ end
42
+
43
+ # A wrapper to get the results within a page
44
+ # @note This wrapper is needed to define the items alias method
45
+ # @return [Array]
46
+ # @example Return the items array within the page
47
+ # Starwars::Planet.fetch_all.results
48
+ # Starwars::Planet.fetch_all.items
49
+ # @api public
50
+ def results
51
+ self[:results]
52
+ end
53
+
54
+ # Checks wheather this is the last page
55
+ # @return [Boolean]
56
+ # @example are we at the last page?
57
+ # Starwars::Planet.fetch_all.last_page?
58
+ # @api public
59
+ def last_page?
60
+ !next_page?
61
+ end
62
+
63
+ # Checks wheather this there is more pages
64
+ # @return [Boolean]
65
+ # @example do we have a next page?
66
+ # Starwars::Planet.fetch_all.next_page?
67
+ # @api public
68
+ def next_page?
69
+ !self.next.nil?
70
+ end
71
+
72
+ # Returns the next page
73
+ # @return [Starwars::Base]
74
+ # @example fetch the next page
75
+ # page = Starwars::Planet.fetch_all
76
+ # page.next_page
77
+ # @api public
78
+ def next_page
79
+ return if last_page?
80
+ perform_request
81
+ end
82
+
83
+ # Yields the subsequent page responses to a given block
84
+ # @yieldparam [Starwars::Base] response
85
+ # @return [Enumerable, nil]
86
+ # @example fetch the next page
87
+ # Starwars::Planet.fetch_all.each_page{|page| p page.items.map(&:name)}
88
+ # Starwars::Planet.fetch_all.each{|page| p page.items.map(&:name)}
89
+ # Starwars::Planet.fetch_all.each_with_index{|page, index|
90
+ # p page.items.map(&:name)
91
+ # }
92
+ # @api public
93
+ def each_page
94
+ return to_enum(__callee__) unless block_given?
95
+ yield(next_page) until last_page?
96
+ end
97
+
98
+ alias_method :each, :each_page
99
+ alias_method :items, :results
100
+
101
+ private
102
+
103
+ # Delegate to the request class to perform fetch data from remote server
104
+ # @return [People, Films, Planets, Species, Starships, Vehicles]
105
+ # @api private
106
+ def perform_request
107
+ Request.new(request_attributes(uri: self.next)).perform_request
108
+ end
109
+ end
110
+ end