github_api 0.9.7 → 0.10.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 (60) hide show
  1. data/README.md +24 -14
  2. data/features/cassettes/media/get_default.yml +84 -0
  3. data/features/cassettes/media/get_full_json.yml +83 -0
  4. data/features/cassettes/media/get_html_json.yml +81 -0
  5. data/features/cassettes/media/get_raw_json.yml +80 -0
  6. data/features/cassettes/media/get_text_json.yml +80 -0
  7. data/features/cassettes/repos/stats/commits.yml +80 -0
  8. data/features/cassettes/repos/stats/contribs.yml +221 -0
  9. data/features/cassettes/repos/stats/frequency.yml +54 -0
  10. data/features/cassettes/repos/stats/participation.yml +68 -0
  11. data/features/cassettes/repos/stats/punch.yml +76 -0
  12. data/features/cassettes/search/users_keyword.yml +70 -0
  13. data/features/gitignore.feature +1 -1
  14. data/features/media_type.feature +76 -0
  15. data/features/repos/statistics.feature +60 -0
  16. data/features/search.feature +11 -0
  17. data/features/step_definitions/github_api_steps.rb +4 -0
  18. data/lib/github_api.rb +2 -0
  19. data/lib/github_api/arguments.rb +1 -1
  20. data/lib/github_api/authorization.rb +1 -1
  21. data/lib/github_api/connection.rb +5 -7
  22. data/lib/github_api/core_ext/deep_merge.rb +13 -0
  23. data/lib/github_api/git_data/trees.rb +1 -1
  24. data/lib/github_api/gitignore.rb +5 -4
  25. data/lib/github_api/markdown.rb +7 -5
  26. data/lib/github_api/mime_type.rb +19 -41
  27. data/lib/github_api/paged_request.rb +1 -1
  28. data/lib/github_api/parameter_filter.rb +1 -1
  29. data/lib/github_api/params_hash.rb +59 -22
  30. data/lib/github_api/repos.rb +9 -3
  31. data/lib/github_api/repos/pub_sub_hubbub.rb +4 -2
  32. data/lib/github_api/repos/statistics.rb +94 -0
  33. data/lib/github_api/request.rb +17 -28
  34. data/lib/github_api/response_wrapper.rb +8 -0
  35. data/lib/github_api/say.rb +2 -1
  36. data/lib/github_api/scopes.rb +3 -2
  37. data/lib/github_api/search.rb +3 -3
  38. data/lib/github_api/utils/url.rb +5 -2
  39. data/lib/github_api/version.rb +2 -2
  40. data/spec/fixtures/repos/commit_activity.json +15 -0
  41. data/spec/fixtures/repos/contribs.json +20 -0
  42. data/spec/fixtures/repos/frequency.json +7 -0
  43. data/spec/fixtures/repos/participation.json +110 -0
  44. data/spec/fixtures/repos/punch_card.json +17 -0
  45. data/spec/github/arguments/parse_spec.rb +2 -2
  46. data/spec/github/core_ext/deep_merge_spec.rb +23 -0
  47. data/spec/github/git_data/trees/create_spec.rb +6 -0
  48. data/spec/github/gitignore/get_spec.rb +1 -1
  49. data/spec/github/mime_type_spec.rb +24 -55
  50. data/spec/github/params_hash_spec.rb +64 -0
  51. data/spec/github/pull_requests/list_spec.rb +1 -1
  52. data/spec/github/repos/statistics/code_frequency_spec.rb +25 -0
  53. data/spec/github/repos/statistics/commit_activity_spec.rb +29 -0
  54. data/spec/github/repos/statistics/contributors_spec.rb +29 -0
  55. data/spec/github/repos/statistics/participation_spec.rb +25 -0
  56. data/spec/github/repos/statistics/punch_card_spec.rb +25 -0
  57. data/spec/github/request_spec.rb +10 -11
  58. data/spec/github/response_wrapper/overwrites_spec.rb +19 -0
  59. data/spec/github/users/keys/update_spec.rb +1 -1
  60. metadata +73 -34
@@ -0,0 +1,70 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: get
5
+ uri: https://<BASIC_AUTH>@api.github.com/legacy/user/search/location:Sheffield%20repos:20?access_token=<TOKEN>
6
+ body:
7
+ encoding: US-ASCII
8
+ string: ''
9
+ headers:
10
+ Accept:
11
+ - application/vnd.github.v3.full+json,application/vnd.github.beta.full+json;q=0.7,application/vnd.github+json;q=0.5,application/json;q=0.1
12
+ Accept-Charset:
13
+ - utf-8
14
+ User-Agent:
15
+ - Github Ruby Gem 0.9.7
16
+ Content-Type:
17
+ - application/json
18
+ Accept-Encoding:
19
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
20
+ response:
21
+ status:
22
+ code: 200
23
+ message: OK
24
+ headers:
25
+ Server:
26
+ - GitHub.com
27
+ Date:
28
+ - Sat, 18 May 2013 13:33:41 GMT
29
+ Content-Type:
30
+ - application/json; charset=utf-8
31
+ Transfer-Encoding:
32
+ - chunked
33
+ Connection:
34
+ - keep-alive
35
+ Status:
36
+ - 200 OK
37
+ X-Ratelimit-Limit:
38
+ - '5000'
39
+ X-Ratelimit-Remaining:
40
+ - '4999'
41
+ X-Github-Media-Type:
42
+ - github.v3; param=full; format=json
43
+ X-Content-Type-Options:
44
+ - nosniff
45
+ Access-Control-Allow-Credentials:
46
+ - 'true'
47
+ Access-Control-Expose-Headers:
48
+ - Link, X-RateLimit-Limit, X-RateLimit-Remaining, X-OAuth-Scopes, X-Accepted-OAuth-Scopes
49
+ Access-Control-Allow-Origin:
50
+ - ! '*'
51
+ Etag:
52
+ - ! '"719c73d7273332047f0d1eacf695cedd"'
53
+ Cache-Control:
54
+ - max-age=0, private, must-revalidate
55
+ Vary:
56
+ - Accept-Encoding
57
+ Content-Encoding:
58
+ - gzip
59
+ body:
60
+ encoding: ASCII-8BIT
61
+ string: !binary |-
62
+ H4sIAAAAAAAAA3WQ3WrDMAyFXyX4uh124qRJXmEMxn5uNkZQ/JMaHDs49kYp
63
+ fffJoYXBNvCFj/Tp6KAzSasKK+nfz8RI0m9yzzmvWEl2ZArwCRHCsPX0WPJO
64
+ 1nXDgepW1EDHplNUHpis2453OJDHHcwK6UVFtJpTAHHEjvWTcb/LV/jR+BiK
65
+ hxusk7V/d6wXEI3PTs9HpbVRVu6KV2eiksW9cZP0c94Gbkow5RxPaTxhJZ6W
66
+ rHJAVEsarRFDUIsfhE8ukr6kO5I1HiN/tbfWf223qZof8obn4ip8QFN2h7wI
67
+ CjDDAGhFSsroPr/2hR36ivWUvuHWK/MfcPm4fAP71GbikAEAAA==
68
+ http_version: !!null
69
+ recorded_at: Sat, 18 May 2013 13:33:41 GMT
70
+ recorded_with: VCR 2.4.0
@@ -29,7 +29,7 @@ Feature: Markdown API
29
29
  | template_name |
30
30
  | Ruby |
31
31
  And I pass the following request options:
32
- | mime |
32
+ | accept |
33
33
  | application/vnd.github.raw |
34
34
  When I make request within a cassette named "gitignore/get_raw"
35
35
  Then the response status should be 200
@@ -0,0 +1,76 @@
1
+ Feature: Media Type
2
+
3
+ Background:
4
+ Given I have "Github::Issues" instance
5
+
6
+ Scenario: Default media
7
+
8
+ Given I want to get resource with the following params:
9
+ | user | repo | issue_id |
10
+ | peter-murach | github | 108 |
11
+ When I make request within a cassette named "media/get_default"
12
+ Then the response status should be 200
13
+ And the request header Accept should be
14
+ """
15
+ application/vnd.github.v3+json,application/vnd.github.beta+json;q=0.5,application/json;q=0.1
16
+ """
17
+
18
+ Scenario: Raw media
19
+
20
+ Given I want to get resource with the following params:
21
+ | user | repo | issue_id |
22
+ | peter-murach | github | 108 |
23
+ And I pass the following request options:
24
+ | media |
25
+ | raw |
26
+ When I make request within a cassette named "media/get_raw_json"
27
+ Then the response status should be 200
28
+ And the request header Accept should be
29
+ """
30
+ application/vnd.github.v3.raw+json
31
+ """
32
+
33
+ Scenario: Text media
34
+
35
+ Given I want to get resource with the following params:
36
+ | user | repo | issue_id |
37
+ | peter-murach | github | 108 |
38
+ And I pass the following request options:
39
+ | media |
40
+ | text |
41
+ When I make request within a cassette named "media/get_text_json"
42
+ Then the response status should be 200
43
+ And the request header Accept should be
44
+ """
45
+ application/vnd.github.v3.text+json
46
+ """
47
+
48
+ Scenario: Html media
49
+
50
+ Given I want to get resource with the following params:
51
+ | user | repo | issue_id |
52
+ | peter-murach | github | 108 |
53
+ And I pass the following request options:
54
+ | media |
55
+ | html |
56
+ When I make request within a cassette named "media/get_html_json"
57
+ Then the response status should be 200
58
+ And the request header Accept should be
59
+ """
60
+ application/vnd.github.v3.html+json
61
+ """
62
+
63
+ Scenario: Full media
64
+
65
+ Given I want to get resource with the following params:
66
+ | user | repo | issue_id |
67
+ | peter-murach | github | 108 |
68
+ And I pass the following request options:
69
+ | media |
70
+ | beta.full |
71
+ When I make request within a cassette named "media/get_full_json"
72
+ Then the response status should be 200
73
+ And the request header Accept should be
74
+ """
75
+ application/vnd.github.beta.full+json
76
+ """
@@ -0,0 +1,60 @@
1
+ Feature: Statistics API
2
+
3
+ Background:
4
+ Given I have "Github::Repos::Statistics" instance
5
+
6
+ Scenario: Contributors
7
+
8
+ Given I want contributors resources
9
+ And I pass the following request options:
10
+ | user | repo |
11
+ | peter-murach | github |
12
+ When I make request within a cassette named "repos/stats/contribs"
13
+ Then the response status should be 200
14
+ And the response type should be JSON
15
+ And the response should not be empty
16
+
17
+ Scenario: Commit Activity
18
+
19
+ Given I want commit_activity resources
20
+ And I pass the following request options:
21
+ | user | repo |
22
+ | peter-murach | github |
23
+ When I make request within a cassette named "repos/stats/commits"
24
+ Then the response status should be 200
25
+ And the response type should be JSON
26
+ And the response should not be empty
27
+
28
+ # Scenario: Code Frequency
29
+ #
30
+ # Given I want code_frequency resources
31
+ # And I pass the following request options:
32
+ # | user | repo |
33
+ # | peter-murach | github |
34
+ # When I make request within a cassette named "repos/stats/frequency"
35
+ # Then the response status should be 200
36
+ # And the response type should be JSON
37
+ # And the response should not be empty
38
+
39
+ Scenario: Participation
40
+
41
+ Given I want participation resources
42
+ And I pass the following request options:
43
+ | user | repo |
44
+ | peter-murach | github |
45
+ When I make request within a cassette named "repos/stats/participation"
46
+ Then the response status should be 200
47
+ And the response type should be JSON
48
+ And the response should not be empty
49
+
50
+ Scenario: Punch Card
51
+
52
+ Given I want punch_card resources
53
+ And I pass the following request options:
54
+ | user | repo |
55
+ | peter-murach | github |
56
+ When I make request within a cassette named "repos/stats/punch"
57
+ Then the response status should be 200
58
+ And the response type should be JSON
59
+ And the response should not be empty
60
+
@@ -36,6 +36,17 @@ Feature: Search API
36
36
  And the response type should be JSON
37
37
  And the response should not be empty
38
38
 
39
+ Scenario: Users with complex keyword
40
+
41
+ Given I want users resource
42
+ And I pass the following request options:
43
+ | keyword |
44
+ | location:Sheffield repos:20 |
45
+ When I make request within a cassette named "search/users_keyword"
46
+ Then the response status should be 200
47
+ And the response type should be JSON
48
+ And the response should not be empty
49
+
39
50
  Scenario: Email
40
51
 
41
52
  Given I want email resource
@@ -71,6 +71,10 @@ When /^I iterate through collection pages$/ do
71
71
  end
72
72
  end
73
73
 
74
+ Then /^the request header (.*) should be$/ do |header, value|
75
+ expect(@response.headers.env[:request_headers][header]).to eql(value)
76
+ end
77
+
74
78
  Then /^the response collection of resources is different for "([^"]*)" attribute$/ do |attr|
75
79
  @next_response.first.send(:"#{attr}").should_not eql @response.first.send(:"#{attr}")
76
80
  end
@@ -7,6 +7,7 @@ require 'github_api/utils/url'
7
7
  require 'github_api/connection'
8
8
  require 'github_api/deprecation'
9
9
  require 'github_api/core_ext/ordered_hash'
10
+ require 'github_api/core_ext/deep_merge'
10
11
 
11
12
  module Github
12
13
  extend Configuration
@@ -90,6 +91,7 @@ module Github
90
91
  :PagedRequest => 'paged_request',
91
92
  :Validations => 'validations',
92
93
  :ParameterFilter => 'parameter_filter',
94
+ :ParamsHash => 'params_hash',
93
95
  :Normalizer => 'normalizer'
94
96
 
95
97
  end # Github
@@ -45,7 +45,7 @@ module Github
45
45
  # Arguments can be part of parameters hash or be simple string arguments.
46
46
  #
47
47
  def parse(*args, &block)
48
- options = args.extract_options!
48
+ options = ParamsHash.new(args.extract_options!)
49
49
  normalize! options
50
50
 
51
51
  if !args.size.zero?
@@ -25,7 +25,7 @@ module Github
25
25
 
26
26
  # Sends authorization request to GitHub.
27
27
  # = Parameters
28
- # * <tt>:redirect_uri</tt> - Required string.
28
+ # * <tt>:redirect_uri</tt> - Optional string.
29
29
  # * <tt>:scope</tt> - Optional string. Comma separated list of scopes.
30
30
  # Available scopes:
31
31
  # * (no scope) - public read-only access (includes public user profile info, public repo info, and gists).
@@ -26,17 +26,15 @@ module Github
26
26
  def default_options(options={})
27
27
  {
28
28
  :headers => {
29
- ACCEPT => "application/vnd.github.v3.full+json," \
30
- "application/vnd.github.beta.full+json;q=0.7," \
31
- "application/vnd.github+json;q=0.5," \
29
+ ACCEPT => "application/vnd.github.v3+json," \
30
+ "application/vnd.github.beta+json;q=0.5," \
32
31
  "application/json;q=0.1",
33
32
  ACCEPT_CHARSET => "utf-8",
34
- USER_AGENT => user_agent,
35
- CONTENT_TYPE => 'application/json'
33
+ USER_AGENT => user_agent
36
34
  },
37
- :ssl => options.fetch(:ssl) { ssl },
35
+ :ssl => ssl,
38
36
  :url => options.fetch(:endpoint) { Github.endpoint }
39
- }.merge(options)
37
+ }.deep_merge(options)
40
38
  end
41
39
 
42
40
  # Default middleware stack that uses default adapter as specified at
@@ -0,0 +1,13 @@
1
+ class Hash
2
+ def deep_merge(other)
3
+ dup.deep_merge!(other)
4
+ end
5
+
6
+ def deep_merge!(other)
7
+ other.each_pair do |key, val|
8
+ tval = self[key]
9
+ self[key] = tval.is_a?(Hash) && val.is_a?(Hash) ? tval.deep_merge(val) : val
10
+ end
11
+ self
12
+ end
13
+ end
@@ -81,7 +81,7 @@ module Github
81
81
  def create(*args)
82
82
  arguments(args, :required => [:user, :repo]) do
83
83
  assert_required %w[ tree ]
84
- sift VALID_TREE_PARAM_NAMES, 'tree'
84
+ sift VALID_TREE_PARAM_NAMES, 'tree', { recursive: true }
85
85
  assert_values VALID_TREE_PARAM_VALUES, 'tree'
86
86
  end
87
87
 
@@ -32,16 +32,17 @@ module Github
32
32
  #
33
33
  # = Examples
34
34
  # github = Github.new
35
- # github.gitignore.get "template-name", mime: 'applicatin/vnd.github.raw'
35
+ # github.gitignore.get "template-name", accept: 'applicatin/vnd.github.raw'
36
36
  #
37
37
  def get(*args)
38
38
  params = arguments(args, :required => [:name]).params
39
39
 
40
- if (mime_type = params.delete('mime'))
41
- options = { :raw => true, :headers => {'Accept' => mime_type} }
40
+ if (media = params.delete('accept'))
41
+ params['accept'] = media
42
+ params['raw'] = true
42
43
  end
43
44
 
44
- get_request("/gitignore/templates/#{name}", params, options || {})
45
+ get_request("/gitignore/templates/#{name}", params)
45
46
  end
46
47
  alias :find :get
47
48
 
@@ -28,11 +28,12 @@ module Github
28
28
  arguments(args) do
29
29
  assert_required ['text']
30
30
  end
31
+ params = arguments.params
32
+ params['raw'] = true
31
33
 
32
- post_request("markdown", arguments.params, :raw => true)
34
+ post_request("markdown", arguments.params)
33
35
  end
34
36
 
35
-
36
37
  # Render a Markdown document in raw mode
37
38
  #
38
39
  # = Input
@@ -44,14 +45,15 @@ module Github
44
45
  # = Examples
45
46
  # github = Github.new
46
47
  # github.markdown.render_raw "Hello github/linguist#1 **cool**, and #1!",
47
- # "mime": "text/plain",
48
+ # "accept": "text/plain",
48
49
  #
49
50
  def render_raw(*args)
50
51
  params = arguments(args).params
51
52
  mime_type, params['data'] = params['mime'], args.shift
53
+ params['raw'] = true
54
+ params['accept'] = params.fetch('accept') { 'text/plain' }
52
55
 
53
- post_request("markdown/raw", params, :raw => true,
54
- :headers => {'Content-Type' => mime_type || 'text/plain'})
56
+ post_request("markdown/raw", params)
55
57
  end
56
58
 
57
59
  end # Markdown
@@ -3,51 +3,29 @@
3
3
  module Github
4
4
  module MimeType
5
5
 
6
- attr_accessor :accepts
7
-
8
- RESOURCE_LOOKUP = {
9
- :json => 'json',
10
- :issue => 'vnd.github-issue.',
11
- :issue_comment => 'vnd.github-issuecomment.',
12
- :commit_comment => 'vnd.github-commitcomment.',
13
- :pull_request => 'vnd.github-pull.',
14
- :pull_comment => 'vnd.github-pullcomment.',
15
- :gist_comment => 'vnd.github-gistcomment.',
16
- :blob => 'vnd.github-blob.'
17
- }
18
-
19
- MIME_LOOKUP = {
20
- :json => 'json',
21
- :blob => 'raw',
22
- :raw => 'raw+json',
23
- :text => 'text+json',
24
- :html => 'html+json',
25
- :full => 'full+json'
6
+ MEDIA_LOOKUP = {
7
+ 'json' => 'json',
8
+ 'blob' => 'raw',
9
+ 'raw' => 'raw+json',
10
+ 'text' => 'text+json',
11
+ 'html' => 'html+json',
12
+ 'full' => 'full+json'
26
13
  }
27
14
 
28
- def parse(resource = nil, mime_type = :json)
29
- resource = lookup_resource(resource) if resource
30
- mime_type = lookup_mime(mime_type)
31
- self.accepts = "application/#{resource || ''}#{mime_type}"
32
- end
33
-
34
- def lookup_resource(name)
35
- RESOURCE_LOOKUP.fetch(name)
36
- end
37
-
38
- def lookup_mime(name)
39
- MIME_LOOKUP.fetch(name)
15
+ # Parse media type param
16
+ #
17
+ def parse(media)
18
+ version = 'v3'
19
+ media.sub!(/^[.]*|[.]*$/,"")
20
+ media = media.include?('+') ? media.split('+')[0] : media
21
+ version, media = media.split('.') if media.include?('.')
22
+ media_type = lookup_media(media)
23
+ "application/vnd.github.#{version}.#{media_type}"
40
24
  end
41
25
 
42
- def _normalize_name(name)
43
- puts "NAME: #{name}"
44
- case name
45
- when String
46
- name.strip.downcase.to_sym
47
- when Symbol
48
- name
49
- else
50
- raise ArgumentError, 'Provided MIME Type is not a valid or recognized entry'
26
+ def lookup_media(name)
27
+ MEDIA_LOOKUP.fetch(name) do
28
+ raise ArgumentError, "Provided Media Type #{name} is not valid"
51
29
  end
52
30
  end
53
31