git_reflow 0.8.6 → 0.8.7

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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/CHANGELOG.md +348 -348
  4. data/Gemfile.lock +13 -15
  5. data/LICENSE +20 -20
  6. data/README.rdoc +461 -461
  7. data/Rakefile +8 -8
  8. data/bin/console +7 -7
  9. data/bin/setup +6 -6
  10. data/circle.yml +5 -5
  11. data/exe/git-reflow +36 -36
  12. data/git_reflow.gemspec +1 -1
  13. data/lib/git_reflow/commands/deliver.rb +10 -10
  14. data/lib/git_reflow/commands/refresh.rb +20 -20
  15. data/lib/git_reflow/commands/review.rb +13 -13
  16. data/lib/git_reflow/commands/setup.rb +11 -11
  17. data/lib/git_reflow/commands/stage.rb +9 -9
  18. data/lib/git_reflow/commands/start.rb +22 -22
  19. data/lib/git_reflow/commands/status.rb +7 -7
  20. data/lib/git_reflow/config.rb +9 -9
  21. data/lib/git_reflow/git_server/base.rb +68 -68
  22. data/lib/git_reflow/git_server/bit_bucket/pull_request.rb +84 -84
  23. data/lib/git_reflow/git_server/bit_bucket.rb +101 -101
  24. data/lib/git_reflow/git_server/git_hub/pull_request.rb +4 -1
  25. data/lib/git_reflow/git_server/pull_request.rb +11 -2
  26. data/lib/git_reflow/git_server.rb +63 -63
  27. data/lib/git_reflow/logger.rb +49 -0
  28. data/lib/git_reflow/merge_error.rb +9 -9
  29. data/lib/git_reflow/os_detector.rb +23 -23
  30. data/lib/git_reflow/rspec/command_line_helpers.rb +12 -8
  31. data/lib/git_reflow/rspec/stub_helpers.rb +13 -13
  32. data/lib/git_reflow/rspec.rb +2 -2
  33. data/lib/git_reflow/sandbox.rb +11 -6
  34. data/lib/git_reflow/version.rb +1 -1
  35. data/lib/git_reflow/workflow.rb +59 -59
  36. data/lib/git_reflow/workflows/core.rb +238 -238
  37. data/lib/git_reflow/workflows/flat_merge.rb +10 -10
  38. data/lib/git_reflow.rb +11 -0
  39. data/spec/fixtures/awesome_workflow.rb +7 -0
  40. data/spec/fixtures/git/git_config +7 -0
  41. data/spec/fixtures/issues/comment.json.erb +27 -0
  42. data/spec/fixtures/issues/comments.json +29 -0
  43. data/spec/fixtures/issues/comments.json.erb +15 -0
  44. data/spec/fixtures/pull_requests/comment.json.erb +45 -0
  45. data/spec/fixtures/pull_requests/comments.json +47 -0
  46. data/spec/fixtures/pull_requests/comments.json.erb +15 -0
  47. data/spec/fixtures/pull_requests/commits.json +29 -0
  48. data/spec/fixtures/pull_requests/external_pull_request.json +145 -0
  49. data/spec/fixtures/pull_requests/pull_request.json +142 -0
  50. data/spec/fixtures/pull_requests/pull_request.json.erb +142 -0
  51. data/spec/fixtures/pull_requests/pull_request_exists_error.json +32 -0
  52. data/spec/fixtures/pull_requests/pull_requests.json +136 -0
  53. data/spec/fixtures/repositories/commit.json +53 -0
  54. data/spec/fixtures/repositories/commit.json.erb +53 -0
  55. data/spec/fixtures/repositories/commits.json.erb +13 -0
  56. data/spec/fixtures/repositories/statuses.json +31 -0
  57. data/spec/fixtures/workflow_with_super.rb +8 -0
  58. data/spec/lib/git_reflow/config_spec.rb +74 -0
  59. data/spec/lib/git_reflow/git_helpers_spec.rb +182 -0
  60. data/spec/lib/git_reflow/git_server/bit_bucket_spec.rb +81 -0
  61. data/spec/lib/git_reflow/git_server/git_hub/pull_request_spec.rb +587 -0
  62. data/spec/lib/git_reflow/git_server/git_hub_spec.rb +221 -0
  63. data/spec/lib/git_reflow/git_server/pull_request_spec.rb +524 -0
  64. data/spec/lib/git_reflow/git_server_spec.rb +101 -0
  65. data/spec/lib/git_reflow/logger_spec.rb +18 -0
  66. data/spec/lib/git_reflow/sandbox_spec.rb +15 -0
  67. data/spec/lib/git_reflow/workflow_spec.rb +59 -0
  68. data/spec/lib/git_reflow/workflows/core_spec.rb +665 -0
  69. data/spec/lib/git_reflow/workflows/flat_merge_spec.rb +59 -0
  70. data/spec/lib/git_reflow_spec.rb +75 -0
  71. data/spec/spec_helper.rb +38 -0
  72. data/spec/support/fake_github.rb +128 -0
  73. data/spec/support/fixtures.rb +54 -0
  74. data/spec/support/github_helpers.rb +109 -0
  75. data/spec/support/mock_pull_request.rb +17 -0
  76. data/spec/support/web_mocks.rb +39 -0
  77. metadata +83 -6
@@ -0,0 +1,136 @@
1
+ [
2
+ {
3
+ "url": "https://api.github.com/reenhanced/repo/pulls/1",
4
+ "html_url": "https://github.com/reenhanced/repo/pulls/1",
5
+ "diff_url": "https://github.com/reenhanced/repo/pulls/1.diff",
6
+ "patch_url": "https://github.com/reenhanced/repo/pulls/1.patch",
7
+ "issue_url": "https://github.com/reenhanced/repo/issue/1",
8
+ "number": 1,
9
+ "state": "open",
10
+ "title": "new-feature",
11
+ "body": "Please pull these awesome changes",
12
+ "created_at": "2011-01-26T19:01:12Z",
13
+ "updated_at": "2011-01-26T19:01:12Z",
14
+ "closed_at": "2011-01-26T19:01:12Z",
15
+ "merged_at": "2011-01-26T19:01:12Z",
16
+ "user": {
17
+ "login": "reenhanced",
18
+ "id": 1,
19
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
20
+ "gravatar_id": "",
21
+ "url": "https://api.github.com/users/reenhanced",
22
+ "html_url": "https://github.com/reenhanced",
23
+ "followers_url": "https://api.github.com/users/reenhanced/followers",
24
+ "following_url": "https://api.github.com/users/reenhanced/following{/other_user}",
25
+ "gists_url": "https://api.github.com/users/reenhanced/gists{/gist_id}",
26
+ "starred_url": "https://api.github.com/users/reenhanced/starred{/owner}{/repo}",
27
+ "subscriptions_url": "https://api.github.com/users/reenhanced/subscriptions",
28
+ "organizations_url": "https://api.github.com/users/reenhanced/orgs",
29
+ "repos_url": "https://api.github.com/users/reenhanced/repos",
30
+ "events_url": "https://api.github.com/users/reenhanced/events{/privacy}",
31
+ "received_events_url": "https://api.github.com/users/reenhanced/received_events",
32
+ "type": "User",
33
+ "site_admin": false
34
+ },
35
+ "head": {
36
+ "label": "new-feature",
37
+ "ref": "new-feature",
38
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
39
+ "user": {
40
+ "login": "reenhanced",
41
+ "id": 1,
42
+ "avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
43
+ "gravatar_id": "somehexcode",
44
+ "url": "https://api.github.com/users/reenhanced"
45
+ },
46
+ "repo": {
47
+ "url": "https://api.github.com/repos/reenhanced/repo",
48
+ "html_url": "https://github.com/reenhanced/repo",
49
+ "clone_url": "https://github.com/reenhanced/repo.git",
50
+ "git_url": "git://github.com/reenhanced/repo.git",
51
+ "ssh_url": "git@github.com:reenhanced/repo.git",
52
+ "svn_url": "https://svn.github.com/reenhanced/repo",
53
+ "mirror_url": "git://git.example.com/reenhanced/repo",
54
+ "id": 1296269,
55
+ "owner": {
56
+ "login": "reenhanced",
57
+ "id": 1,
58
+ "avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
59
+ "gravatar_id": "somehexcode",
60
+ "url": "https://api.github.com/users/reenhanced"
61
+ },
62
+ "name": "repo",
63
+ "description": "This your first repo!",
64
+ "homepage": "https://github.com",
65
+ "language": null,
66
+ "private": false,
67
+ "fork": false,
68
+ "forks": 9,
69
+ "watchers": 80,
70
+ "size": 108,
71
+ "master_branch": "master",
72
+ "open_issues": 0,
73
+ "pushed_at": "2011-01-26T19:06:43Z",
74
+ "created_at": "2011-01-26T19:01:12Z",
75
+ "updated_at": "2011-01-26T19:14:43Z"
76
+ }
77
+ },
78
+ "base": {
79
+ "label": "master",
80
+ "ref": "master",
81
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
82
+ "user": {
83
+ "login": "reenhanced",
84
+ "id": 1,
85
+ "avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
86
+ "gravatar_id": "somehexcode",
87
+ "url": "https://api.github.com/users/reenhanced"
88
+ },
89
+ "repo": {
90
+ "url": "https://api.github.com/repos/reenhanced/repo",
91
+ "html_url": "https://github.com/reenhanced/repo",
92
+ "clone_url": "https://github.com/reenhanced/repo.git",
93
+ "git_url": "git://github.com/reenhanced/repo.git",
94
+ "ssh_url": "git@github.com:reenhanced/repo.git",
95
+ "svn_url": "https://svn.github.com/reenhanced/repo",
96
+ "mirror_url": "git://git.example.com/reenhanced/repo",
97
+ "id": 1296269,
98
+ "owner": {
99
+ "login": "reenhanced",
100
+ "id": 1,
101
+ "avatar_url": "https://github.com/images/error/reenhanced_happy.gif",
102
+ "gravatar_id": "somehexcode",
103
+ "url": "https://api.github.com/users/reenhanced"
104
+ },
105
+ "name": "repo",
106
+ "description": "This your first repo!",
107
+ "homepage": "https://github.com",
108
+ "language": null,
109
+ "private": false,
110
+ "fork": false,
111
+ "forks": 9,
112
+ "watchers": 80,
113
+ "size": 108,
114
+ "master_branch": "master",
115
+ "open_issues": 0,
116
+ "pushed_at": "2011-01-26T19:06:43Z",
117
+ "created_at": "2011-01-26T19:01:12Z",
118
+ "updated_at": "2011-01-26T19:14:43Z"
119
+ }
120
+ },
121
+ "_links": {
122
+ "self": {
123
+ "href": "https://api.github.com/reenhanced/repo/pulls/1"
124
+ },
125
+ "html": {
126
+ "href": "https://github.com/reenhanced/repo/pull/1"
127
+ },
128
+ "comments": {
129
+ "href": "https://api.github.com/reenhanced/repo/issues/1/comments"
130
+ },
131
+ "review_comments": {
132
+ "href": "https://api.github.com/reenhanced/repo/pulls/1/comments"
133
+ }
134
+ }
135
+ }
136
+ ]
@@ -0,0 +1,53 @@
1
+ {
2
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
3
+ "commit": {
4
+ "url": "https://api.github.com/repos/reenhanced/repo/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
5
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
6
+ "author": {
7
+ "name": "Monalisa Octocat",
8
+ "email": "support@github.com",
9
+ "date": "2011-04-14T16:00:49Z"
10
+ },
11
+ "committer": {
12
+ "name": "Monalisa Octocat",
13
+ "email": "support@github.com",
14
+ "date": "2011-04-14T16:00:49Z"
15
+ },
16
+ "message": "Fix all the bugs",
17
+ "tree": {
18
+ "url": "https://api.github.com/repos/reenhanced/repo/tree/6dcb09b5b57875f334f61aebed695e2e4193db5e",
19
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
20
+ }
21
+ },
22
+ "author": {
23
+ "login": "reenhanced",
24
+ "id": 1,
25
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
26
+ "url": "https://api.github.com/users/reenhanced"
27
+ },
28
+ "committer": {
29
+ "login": "reenhanced",
30
+ "id": 1,
31
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
32
+ "url": "https://api.github.com/users/reenhanced"
33
+ },
34
+ "parents": [
35
+ {
36
+ "url": "https://api.github.com/repos/reenhanced/repo/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
37
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
38
+ }
39
+ ],
40
+ "stats": {
41
+ "additions": 104,
42
+ "deletions": 4,
43
+ "total": 108
44
+ },
45
+ "files": [
46
+ {
47
+ "filename": "file1.txt",
48
+ "additions": 10,
49
+ "deletions": 2,
50
+ "total": 12
51
+ }
52
+ ]
53
+ }
@@ -0,0 +1,53 @@
1
+ {
2
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
3
+ "commit": {
4
+ "url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/git/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
5
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e",
6
+ "author": {
7
+ "name": "Monalisa Octocat",
8
+ "email": "support@github.com",
9
+ "date": "<%= created_at || "2011-04-14T16:00:49Z" %>"
10
+ },
11
+ "committer": {
12
+ "name": "Monalisa Octocat",
13
+ "email": "support@github.com",
14
+ "date": "<%= created_at || "2011-04-14T16:00:49Z" %>"
15
+ },
16
+ "message": "Fix all the bugs",
17
+ "tree": {
18
+ "url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/tree/6dcb09b5b57875f334f61aebed695e2e4193db5e",
19
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
20
+ }
21
+ },
22
+ "author": {
23
+ "login": "<%= author %>",
24
+ "id": 1,
25
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
26
+ "url": "https://api.github.com/users/<%= author %>"
27
+ },
28
+ "committer": {
29
+ "login": "<%= author %>",
30
+ "id": 1,
31
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
32
+ "url": "https://api.github.com/users/<%= author %>"
33
+ },
34
+ "parents": [
35
+ {
36
+ "url": "https://api.github.com/repos/<%= repo_owner %>/<%= repo_name %>/commits/6dcb09b5b57875f334f61aebed695e2e4193db5e",
37
+ "sha": "6dcb09b5b57875f334f61aebed695e2e4193db5e"
38
+ }
39
+ ],
40
+ "stats": {
41
+ "additions": 104,
42
+ "deletions": 4,
43
+ "total": 108
44
+ },
45
+ "files": [
46
+ {
47
+ "filename": "file1.txt",
48
+ "additions": 10,
49
+ "deletions": 2,
50
+ "total": 12
51
+ }
52
+ ]
53
+ }
@@ -0,0 +1,13 @@
1
+ [
2
+ <% commits_json = [] %>
3
+ <% commits.each_with_index do |commit, index| %>
4
+ <% commits_json << Fixture.new('repositories/commit.json.erb',
5
+ id: index,
6
+ author: commit[:author],
7
+ repo_owner: repo_owner,
8
+ repo_name: repo_name,
9
+ created_at: commit[:created_at] || Chronic.parse("October 21, 2015 07:28:00")
10
+ ).to_s %>
11
+ <% end %>
12
+ <%= commits_json.join(", ") %>
13
+ ]
@@ -0,0 +1,31 @@
1
+ [
2
+ {
3
+ "created_at": "2012-07-20T01:19:13Z",
4
+ "updated_at": "2012-07-20T01:19:13Z",
5
+ "state": "success",
6
+ "target_url": "https://ci.example.com/1000/output",
7
+ "description": "Build has completed successfully",
8
+ "id": 1,
9
+ "url": "https://api.github.com/repos/reenhanced/example/statuses/1",
10
+ "context": "continuous-integration/jenkins",
11
+ "creator": {
12
+ "login": "reenhanced",
13
+ "id": 1,
14
+ "avatar_url": "https://github.com/images/error/octocat_happy.gif",
15
+ "gravatar_id": "somehexcode",
16
+ "url": "https://api.github.com/users/reenhanced",
17
+ "html_url": "https://github.com/reenhanced",
18
+ "followers_url": "https://api.github.com/users/reenhanced/followers",
19
+ "following_url": "https://api.github.com/users/reenhanced/following{/other_user}",
20
+ "gists_url": "https://api.github.com/users/reenhanced/gists{/gist_id}",
21
+ "starred_url": "https://api.github.com/users/reenhanced/starred{/owner}{/repo}",
22
+ "subscriptions_url": "https://api.github.com/users/reenhanced/subscriptions",
23
+ "organizations_url": "https://api.github.com/users/reenhanced/orgs",
24
+ "repos_url": "https://api.github.com/users/reenhanced/repos",
25
+ "events_url": "https://api.github.com/users/reenhanced/events{/privacy}",
26
+ "received_events_url": "https://api.github.com/users/reenhanced/received_events",
27
+ "type": "User",
28
+ "site_admin": false
29
+ }
30
+ }
31
+ ]
@@ -0,0 +1,8 @@
1
+ class WorkflowWithSuper < GitReflow::Workflows::Core
2
+ def self.start(**args)
3
+ GitReflow.say "Super."
4
+ super(feature_branch: args[:feature_branch], base: args[:base])
5
+ end
6
+ end
7
+
8
+ WorkflowWithSuper
@@ -0,0 +1,74 @@
1
+ require 'spec_helper'
2
+
3
+ describe GitReflow::Config do
4
+ describe ".get(key)" do
5
+ subject { GitReflow::Config.get('chucknorris.roundhouse') }
6
+ it { expect{ subject }.to have_run_command_silently 'git config --get chucknorris.roundhouse', blocking: false }
7
+
8
+ context "and getting all values" do
9
+ subject { GitReflow::Config.get('chucknorris.roundhouse-kick', all: true) }
10
+ it { expect{ subject }.to have_run_command_silently 'git config --get-all chucknorris.roundhouse-kick', blocking: false }
11
+
12
+ context "and checking locally only" do
13
+ subject { GitReflow::Config.get('chucknorris.jump', local: true) }
14
+ it { expect{ subject }.to have_run_command_silently 'git config --local --get chucknorris.jump', blocking: false }
15
+ end
16
+ end
17
+
18
+ context "and checking for updates" do
19
+ before { GitReflow::Config.get('chucknorris.roundhouse') }
20
+ subject { GitReflow::Config.get('chucknorris.roundhouse') }
21
+ it { expect{ subject }.to_not have_run_command_silently 'git config --get chucknorris.roundhouse-kick', blocking: false }
22
+ end
23
+
24
+ context "and checking locally only" do
25
+ subject { GitReflow::Config.get('chucknorris.smash', local: true) }
26
+ it { expect{ subject }.to have_run_command_silently 'git config --local --get chucknorris.smash', blocking: false }
27
+ end
28
+ end
29
+
30
+ describe ".set(key)" do
31
+ subject { GitReflow::Config.set('chucknorris.roundhouse', 'to the face') }
32
+ it { expect{ subject }.to have_run_command_silently "git config -f #{ENV['HOME']}/.gitconfig.reflow --replace-all chucknorris.roundhouse \"to the face\"", blocking: false }
33
+
34
+ context "for current project only" do
35
+ subject { GitReflow::Config.set('chucknorris.roundhouse', 'to the face', local: true) }
36
+ it { expect{ subject }.to have_run_command_silently 'git config --replace-all chucknorris.roundhouse "to the face"', blocking: false }
37
+ end
38
+ end
39
+
40
+ describe ".unset(key)" do
41
+ subject { GitReflow::Config.unset('chucknorris.roundhouse') }
42
+ it { expect{ subject }.to have_run_command_silently "git config -f #{ENV['HOME']}/.gitconfig.reflow --unset-all chucknorris.roundhouse ", blocking: false }
43
+
44
+ context "for multi-value keys" do
45
+ subject { GitReflow::Config.unset('chucknorris.roundhouse', value: 'to the face') }
46
+ it { expect{ subject }.to have_run_command_silently "git config -f #{ENV['HOME']}/.gitconfig.reflow --unset-all chucknorris.roundhouse \"to the face\"", blocking: false }
47
+ end
48
+
49
+ context "for current project only" do
50
+ subject { GitReflow::Config.unset('chucknorris.roundhouse', local: true) }
51
+ it { expect{ subject }.to have_run_command_silently 'git config --unset-all chucknorris.roundhouse ', blocking: false }
52
+
53
+ context "for multi-value keys" do
54
+ subject { GitReflow::Config.unset('chucknorris.roundhouse', value: 'to the face', local: true) }
55
+ it { expect{ subject }.to have_run_command_silently 'git config --unset-all chucknorris.roundhouse "to the face"', blocking: false }
56
+ end
57
+ end
58
+ end
59
+
60
+ describe ".add(key)" do
61
+ subject { GitReflow::Config.add('chucknorris.roundhouse', 'to the face') }
62
+ it { expect{ subject }.to have_run_command_silently "git config -f #{GitReflow::Config::CONFIG_FILE_PATH} --add chucknorris.roundhouse \"to the face\"", blocking: false }
63
+
64
+ context "for current project only" do
65
+ subject { GitReflow::Config.add('chucknorris.roundhouse', 'to the face', local: true) }
66
+ it { expect{ subject }.to have_run_command_silently 'git config --add chucknorris.roundhouse "to the face"', blocking: false }
67
+ end
68
+
69
+ context "globally" do
70
+ subject { GitReflow::Config.add('chucknorris.roundhouse', 'to the face', global: true) }
71
+ it { expect{ subject }.to have_run_command_silently 'git config --global --add chucknorris.roundhouse "to the face"', blocking: false }
72
+ end
73
+ end
74
+ end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+
3
+ describe GitReflow::GitHelpers do
4
+ let(:origin_url) { 'git@github.com:reenhanced.spectacular/this-is-the.shit.git' }
5
+
6
+ before do
7
+ stub_with_fallback(GitReflow::Config, :get).with('remote.origin.url').and_return(origin_url)
8
+
9
+ module Gitacular
10
+ include GitReflow::GitHelpers
11
+ extend self
12
+ end
13
+
14
+ stub_run_for Gitacular
15
+ end
16
+
17
+ describe ".git_root_dir" do
18
+ subject { Gitacular.git_root_dir }
19
+ it { expect{ subject }.to have_run_command_silently "git rev-parse --show-toplevel" }
20
+ end
21
+
22
+ describe '.git_editor_command' do
23
+ subject { Gitacular.git_editor_command }
24
+ before { ENV['EDITOR'] = 'vim' }
25
+
26
+ it 'defaults to GitReflow config' do
27
+ allow(GitReflow::Config).to receive(:get).with('core.editor').and_return 'nano'
28
+
29
+ expect(subject).to eq 'nano'
30
+ end
31
+
32
+ it 'falls back to the environment variable $EDITOR' do
33
+ allow(GitReflow::Config).to receive(:get).with('core.editor').and_return ''
34
+
35
+ expect(subject).to eq 'vim'
36
+ end
37
+ end
38
+
39
+ describe ".remote_user" do
40
+ subject { Gitacular.remote_user }
41
+
42
+ it { is_expected.to eq('reenhanced.spectacular') }
43
+
44
+ context "remote origin url isn't set" do
45
+ let(:origin_url) { nil }
46
+ it { is_expected.to eq('') }
47
+ end
48
+
49
+ context "remote origin uses HTTP" do
50
+ let(:origin_url) { 'https://github.com/reenhanced.spectacular/this-is-the.shit.git' }
51
+ it { is_expected.to eq('reenhanced.spectacular') }
52
+ end
53
+ end
54
+
55
+ describe ".remote_repo_name" do
56
+ subject { Gitacular.remote_repo_name }
57
+
58
+ it { is_expected.to eq('this-is-the.shit') }
59
+
60
+ context "remote origin url isn't set" do
61
+ let(:origin_url) { nil }
62
+ it { is_expected.to eq('') }
63
+ end
64
+
65
+ context "remote origin uses HTTP" do
66
+ let(:origin_url) { 'https://github.com/reenhanced.spectacular/this-is-the.shit.git' }
67
+ it { is_expected.to eq('this-is-the.shit') }
68
+ end
69
+ end
70
+
71
+ describe ".current_branch" do
72
+ subject { Gitacular.current_branch }
73
+ it { expect{ subject }.to have_run_command_silently "git branch --no-color | grep '^\* ' | grep -v 'no branch' | sed 's/^* //g'" }
74
+ end
75
+
76
+ describe ".pull_request_template" do
77
+ subject { Gitacular.pull_request_template }
78
+
79
+ context "template file exists" do
80
+ let(:root_dir) { "/some_repo" }
81
+ let(:template_content) { "Template content" }
82
+
83
+ before do
84
+ allow(Gitacular).to receive(:git_root_dir).and_return(root_dir)
85
+ allow(File).to receive(:exist?).with("#{root_dir}/.github/PULL_REQUEST_TEMPLATE.md").and_return(true)
86
+ allow(File).to receive(:read).with("#{root_dir}/.github/PULL_REQUEST_TEMPLATE.md").and_return(template_content)
87
+ end
88
+ it { is_expected.to eq template_content }
89
+ end
90
+
91
+ context "template file does not exist" do
92
+ before do
93
+ allow(File).to receive(:exist?).and_return(false)
94
+ end
95
+
96
+ it { is_expected.to be_nil }
97
+ end
98
+ end
99
+
100
+ describe ".get_first_commit_message" do
101
+ subject { Gitacular.get_first_commit_message }
102
+ it { expect{ subject }.to have_run_command_silently 'git log --pretty=format:"%s" --no-merges -n 1' }
103
+ end
104
+
105
+ describe ".push_current_branch" do
106
+ subject { Gitacular.push_current_branch }
107
+ before { allow(Gitacular).to receive(:current_branch).and_return('bingo') }
108
+ it { expect{ subject }.to have_run_command "git push origin bingo" }
109
+ end
110
+
111
+ describe ".fetch_destination(destination_branch)" do
112
+ subject { Gitacular.fetch_destination('new-feature') }
113
+ it { expect{ subject }.to have_run_command "git fetch origin new-feature" }
114
+ end
115
+
116
+ describe ".update_destination(destination_branch)" do
117
+ let(:current_branch) { 'bananas' }
118
+ let(:destination_branch) { 'monkey-business' }
119
+
120
+ before { allow(Gitacular).to receive(:current_branch).and_return(current_branch) }
121
+ subject { Gitacular.update_destination(destination_branch) }
122
+
123
+ it "updates the destination branch with the latest code from the remote repo" do
124
+ expect { subject }.to have_run_commands_in_order [
125
+ "git checkout #{destination_branch}",
126
+ "git pull origin #{destination_branch}",
127
+ "git checkout #{current_branch}"
128
+ ]
129
+ end
130
+ end
131
+
132
+ describe ".update_current_branch" do
133
+ subject { Gitacular.update_current_branch }
134
+ before { allow(Gitacular).to receive(:current_branch).and_return('new-feature') }
135
+
136
+ it "updates the remote changes and pushes any local changes" do
137
+ expect { subject }.to have_run_commands_in_order [
138
+ "git pull origin new-feature",
139
+ "git push origin new-feature"
140
+ ]
141
+ end
142
+ end
143
+
144
+ describe ".update_feature_branch" do
145
+ options = {base: "base", remote: "remote"}
146
+ subject { Gitacular.update_feature_branch(options) }
147
+ before { allow(Gitacular).to receive(:current_branch).and_return('feature') }
148
+
149
+ it "calls the correct methods" do
150
+ expect { subject }.to have_run_commands_in_order [
151
+ "git checkout base",
152
+ "git pull remote base",
153
+ "git checkout feature",
154
+ "git pull origin feature",
155
+ "git merge base"
156
+ ]
157
+ end
158
+ end
159
+
160
+ describe ".append_to_squashed_commit_message(message)" do
161
+ let(:original_squash_message) { "Oooooo, SQUASH IT" }
162
+ let(:message) { "do do the voodoo that you do" }
163
+ let(:root_dir) { '/home/gitreflow' }
164
+ let(:squash_path) { "#{root_dir}/.git/SQUASH_MSG" }
165
+ let(:tmp_squash_path) { "#{root_dir}/.git/tmp_squash_msg" }
166
+ before { allow(Gitacular).to receive(:git_root_dir).and_return(root_dir) }
167
+ subject { Gitacular.append_to_squashed_commit_message(message) }
168
+
169
+ it "appends the message to git's SQUASH_MSG temp file" do
170
+ tmp_file = double('file')
171
+ allow(File).to receive(:open).with(tmp_squash_path, "w").and_yield(tmp_file)
172
+ allow(File).to receive(:exists?).with(squash_path).and_return(true)
173
+ allow(File).to receive(:foreach).with(squash_path).and_yield(original_squash_message)
174
+ expect(tmp_file).to receive(:puts).with(message)
175
+ expect(tmp_file).to receive(:puts).with(original_squash_message)
176
+
177
+ expect { subject }.to have_run_commands_in_order [
178
+ "mv #{tmp_squash_path} #{squash_path}"
179
+ ]
180
+ end
181
+ end
182
+ end
@@ -0,0 +1,81 @@
1
+ require 'spec_helper'
2
+
3
+ describe GitReflow::GitServer::BitBucket do
4
+ let(:user) { 'reenhanced' }
5
+ let(:password) { 'shazam' }
6
+ let(:repo) { 'repo' }
7
+ let(:api_key) { 'a1b2c3d4e5f6g7h8i9j0' }
8
+ let(:hostname) { 'hostname.local' }
9
+ let(:api_endpoint) { 'https://bitbucket.org/api/1.0' }
10
+ let(:site) { 'https://bitbucket.org' }
11
+ let(:remote_url) { "git@bitbucket.org:#{user}/#{repo}.git" }
12
+
13
+ before do
14
+ allow_any_instance_of(HighLine).to receive(:ask) do |terminal, question|
15
+ values = {
16
+ "Please enter your BitBucket username: " => user
17
+ }
18
+ return_value = values[question]
19
+ question = ""
20
+ return_value
21
+ end
22
+ end
23
+
24
+ describe '#initialize(options)' do
25
+ subject { GitReflow::GitServer::BitBucket.new({}) }
26
+
27
+ it 'sets the reflow git server provider to BitBucket in the git config' do
28
+ expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'BitBucket', local: false)
29
+ subject
30
+ end
31
+
32
+ context 'storing git config settings only for this project' do
33
+ subject { GitReflow::GitServer::BitBucket.new(project_only: true) }
34
+
35
+ it 'sets the enterprise site and api as the site and api endpoints for the BitBucket provider in the git config' do
36
+ expect(GitReflow::Config).to receive(:set).once.with('reflow.git-server', 'BitBucket', local: true)
37
+ subject
38
+ end
39
+ end
40
+
41
+ end
42
+
43
+ describe '#authenticate' do
44
+ let(:bitbucket) { GitReflow::GitServer::BitBucket.new( { }) }
45
+ let!(:bitbucket_api) { BitBucket.new }
46
+ subject { bitbucket.authenticate }
47
+
48
+ context 'already authenticated' do
49
+ it "notifies the user of successful setup" do
50
+ allow(GitReflow::Config).to receive(:set).with('reflow.git-server', 'BitBucket', local: false)
51
+ allow(GitReflow::Config).to receive(:get).with('remote.origin.url').and_return(remote_url)
52
+ allow(GitReflow::Config).to receive(:get).with('bitbucket.user', local: false).and_return(user)
53
+ allow(GitReflow::Config).to receive(:get).with('bitbucket.api-key', reload: true, local: false).and_return(api_key)
54
+ allow(GitReflow::Config).to receive(:get).with('reflow.local-projects', all: true).and_return('')
55
+ expect { subject }.to have_said "\nYour BitBucket account was already setup with:"
56
+ expect { subject }.to have_said "\tUser Name: #{user}"
57
+ end
58
+ end
59
+
60
+ context 'not yet authenticated' do
61
+ context 'with valid BitBucket credentials' do
62
+ before do
63
+ allow(GitReflow::Config).to receive(:get).and_return('')
64
+ allow(GitReflow::Config).to receive(:set)
65
+ allow(GitReflow::Config).to receive(:set).with('bitbucket.api-key', reload: true).and_return(api_key)
66
+ allow(GitReflow::Config).to receive(:get).with('bitbucket.api-key', reload: true).and_return('')
67
+ allow(GitReflow::Config).to receive(:get).with('remote.origin.url').and_return(remote_url)
68
+ allow(GitReflow::Config).to receive(:get).with('reflow.local-projects').and_return('')
69
+ allow(bitbucket).to receive(:connection).and_return double(repos: double(all: []))
70
+ end
71
+
72
+ it "prompts me to setup an API key" do
73
+ expect { subject }.to have_said "\nIn order to connect your BitBucket account,"
74
+ expect { subject }.to have_said "you'll need to generate an API key for your team"
75
+ expect { subject }.to have_said "Visit https://bitbucket.org/account/user/reenhanced/api-key/, to generate it\n"
76
+ end
77
+ end
78
+ end
79
+ end
80
+
81
+ end