pgit 0.0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (109) hide show
  1. checksums.yaml +4 -4
  2. data/.agignore +3 -0
  3. data/.travis.yml +1 -0
  4. data/README.markdown +32 -9
  5. data/Rakefile +12 -0
  6. data/bin/pgit +167 -25
  7. data/lib/pgit.rb +40 -10
  8. data/lib/pgit/bilateral/handle_back.rb +22 -0
  9. data/lib/pgit/bilateral/handle_choose_story.rb +31 -0
  10. data/lib/pgit/bilateral/story.rb +44 -0
  11. data/lib/pgit/command.rb +83 -0
  12. data/lib/pgit/command/add.rb +36 -0
  13. data/lib/pgit/command/application.rb +21 -0
  14. data/lib/pgit/command/edit.rb +36 -0
  15. data/lib/pgit/command/remove.rb +36 -0
  16. data/lib/pgit/command/run.rb +32 -0
  17. data/lib/pgit/command/show.rb +53 -0
  18. data/lib/pgit/configuration.rb +27 -3
  19. data/lib/pgit/current_project.rb +9 -45
  20. data/lib/pgit/current_project/validator.rb +2 -1
  21. data/lib/pgit/error/external.rb +11 -0
  22. data/lib/pgit/error/user.rb +12 -0
  23. data/lib/pgit/helpers/heredoc.rb +17 -0
  24. data/lib/pgit/helpers/query_methods.rb +63 -0
  25. data/lib/pgit/helpers/string_extensions.rb +29 -0
  26. data/lib/pgit/installer/bash_auto_completion.rb +57 -0
  27. data/lib/pgit/pivotal/collection_request.rb +21 -0
  28. data/lib/pgit/pivotal/individual_request.rb +47 -0
  29. data/lib/pgit/pivotal/iteration.rb +6 -0
  30. data/lib/pgit/pivotal/iterations.rb +15 -0
  31. data/lib/pgit/pivotal/project.rb +6 -0
  32. data/lib/pgit/pivotal/projects.rb +20 -0
  33. data/lib/pgit/pivotal/query.rb +8 -0
  34. data/lib/pgit/pivotal/request.rb +33 -0
  35. data/lib/pgit/pivotal/request/query.rb +25 -0
  36. data/lib/pgit/pivotal/story.rb +38 -0
  37. data/lib/pgit/pivotal_request_validator.rb +1 -1
  38. data/lib/pgit/project.rb +78 -0
  39. data/lib/pgit/project/add.rb +28 -0
  40. data/lib/pgit/project/application.rb +21 -0
  41. data/lib/pgit/project/interactive_adder.rb +41 -0
  42. data/lib/pgit/project/remove.rb +41 -0
  43. data/lib/pgit/project/reuse_api_token_adder.rb +48 -0
  44. data/lib/pgit/response_handler.rb +16 -0
  45. data/lib/pgit/root.rb +5 -0
  46. data/lib/pgit/status.rb +16 -0
  47. data/lib/pgit/story_branch/application.rb +3 -3
  48. data/lib/pgit/{name_parser.rb → story_branch/name_parser.rb} +0 -0
  49. data/lib/pgit/story_branch/story_id_parser.rb +11 -0
  50. data/lib/pgit/validators/project_validator.rb +20 -0
  51. data/lib/pgit/version.rb +1 -1
  52. data/lib/pivotal +0 -0
  53. data/pgit.gemspec +5 -0
  54. data/spec/fixtures/iterations +1 -0
  55. data/spec/pgit/bilateral/handle_back_spec.rb +29 -0
  56. data/spec/pgit/bilateral/handle_choose_story_spec.rb +17 -0
  57. data/spec/pgit/bilateral/story_spec.rb +178 -0
  58. data/spec/pgit/command/add_spec.rb +68 -0
  59. data/spec/pgit/command/application_spec.rb +110 -0
  60. data/spec/pgit/command/edit_spec.rb +61 -0
  61. data/spec/pgit/command/remove_spec.rb +76 -0
  62. data/spec/pgit/command/run_spec.rb +49 -0
  63. data/spec/pgit/command/show_spec.rb +95 -0
  64. data/spec/pgit/command_spec.rb +299 -0
  65. data/spec/pgit/configuration_spec.rb +121 -18
  66. data/spec/pgit/current_project/validator_spec.rb +2 -1
  67. data/spec/pgit/current_project_spec.rb +20 -71
  68. data/spec/pgit/{external_error_spec.rb → error/external_spec.rb} +3 -3
  69. data/spec/pgit/error/user_spec.rb +17 -0
  70. data/spec/pgit/helpers/heredoc_spec.rb +33 -0
  71. data/spec/pgit/helpers/query_methods_spec.rb +24 -0
  72. data/spec/pgit/helpers/string_extensions_spec.rb +49 -0
  73. data/spec/pgit/installer/bash_auto_completion_spec.rb +134 -0
  74. data/spec/pgit/pivotal/individual_request_spec.rb +32 -0
  75. data/spec/pgit/pivotal/iteration_spec.rb +19 -0
  76. data/spec/pgit/pivotal/iterations_spec.rb +37 -0
  77. data/spec/pgit/pivotal/project_spec.rb +9 -0
  78. data/spec/pgit/pivotal/projects_spec.rb +48 -0
  79. data/spec/pgit/pivotal/request/query_spec.rb +24 -0
  80. data/spec/pgit/pivotal/story_spec.rb +113 -0
  81. data/spec/pgit/pivotal_request_validator_spec.rb +3 -3
  82. data/spec/pgit/project/add_spec.rb +52 -0
  83. data/spec/pgit/project/application_spec.rb +69 -0
  84. data/spec/pgit/project/interactive_adder_spec.rb +45 -0
  85. data/spec/pgit/project/remove_spec.rb +86 -0
  86. data/spec/pgit/project/reuse_api_token_adder_spec.rb +41 -0
  87. data/spec/pgit/project_spec.rb +513 -0
  88. data/spec/pgit/status_spec.rb +40 -0
  89. data/spec/pgit/story_branch/application_spec.rb +5 -8
  90. data/spec/pgit/story_branch/name_parser_spec.rb +3 -3
  91. data/spec/pgit/story_branch/story_id_parser_spec.rb +17 -0
  92. data/spec/pgit/validators/project_validator_spec.rb +39 -0
  93. metadata +146 -21
  94. data/lib/pgit/configuration/layout_error.rb +0 -9
  95. data/lib/pgit/configuration/missing_attributes_error.rb +0 -10
  96. data/lib/pgit/configuration/not_found_error.rb +0 -10
  97. data/lib/pgit/configuration/project_missing_error.rb +0 -10
  98. data/lib/pgit/configuration/validator.rb +0 -41
  99. data/lib/pgit/current_project/no_paths_match_working_dir_error.rb +0 -10
  100. data/lib/pgit/external_error.rb +0 -9
  101. data/lib/pgit/installer/configuration.rb +0 -34
  102. data/lib/pgit/story.rb +0 -44
  103. data/spec/pgit/configuration/missing_attributes_error_spec.rb +0 -30
  104. data/spec/pgit/configuration/not_found_error_spec.rb +0 -17
  105. data/spec/pgit/configuration/project_missing_error_spec.rb +0 -30
  106. data/spec/pgit/configuration/validator_spec.rb +0 -79
  107. data/spec/pgit/current_project/no_paths_match_working_dir_error_spec.rb +0 -17
  108. data/spec/pgit/installer/configuration_spec.rb +0 -162
  109. data/spec/pgit/story_spec.rb +0 -35
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGit::Pivotal::Iterations do
4
+ describe '#get!' do
5
+ it 'makes the correct sublink' do
6
+ project = instance_double('PGit::Project', id: 123, api_token: 'someapitoken')
7
+ allow(PGit::CurrentProject).to receive(:new).and_return(project)
8
+ query = instance_double('PGit::Pivotal::Request::Query', to_s: "?scope=current_backlog")
9
+ hash_query = {scope: :current_backlog}
10
+ allow(PGit::Pivotal::Request::Query).to receive(:new).with(hash_query).and_return(query)
11
+ iterations = PGit::Pivotal::Iterations.new(hash_query)
12
+
13
+ expect(iterations.sublink).to eq "projects/123/iterations/?scope=current_backlog"
14
+ end
15
+
16
+ it 'instantiates iterations' do
17
+ iterations_file = File.read(File.join(PGit.root, 'spec', 'fixtures', 'iterations'))
18
+ iterations_json = JSON.parse(iterations_file)
19
+ first_iteration_json = iterations_json.first
20
+ last_iteration_json = iterations_json.last
21
+ first_iteration = instance_double('PGit::Pivotal::Iteration')
22
+ last_iteration = instance_double('PGit::Pivotal::Iteration')
23
+ fake_iterations = [first_iteration, last_iteration]
24
+ iteration_config = double('config', :hash= => nil)
25
+ allow(PGit::Pivotal::Iteration).to receive(:new).and_yield(iteration_config).and_return(first_iteration, last_iteration)
26
+ project = instance_double('PGit::Project', api_token: double('api_token'), id: double('id'))
27
+ allow(PGit::CurrentProject).to receive(:new).and_return(project)
28
+ iterations_instance = PGit::Pivotal::Iterations.new(project)
29
+ allow(iterations_instance).to receive(:get_request).and_return(iterations_file)
30
+
31
+ iterations = iterations_instance.get!
32
+
33
+ expect(iterations.first).to eq first_iteration
34
+ expect(iterations.last).to eq last_iteration
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,9 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGit::Pivotal::Project do
4
+ describe '.ancestors' do
5
+ it 'should include PGit::Pivotal::IndividualRequest' do
6
+ expect(PGit::Pivotal::Project.ancestors).to include(PGit::Pivotal::IndividualRequest)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,48 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGit::Pivotal::Projects do
4
+ it 'should be a CollectionRequest' do
5
+ expect(PGit::Pivotal::Projects.ancestors).to include(PGit::Pivotal::CollectionRequest)
6
+ end
7
+
8
+ describe 'get!' do
9
+ it 'should instantiate a bunch of PGit::Pivotal::Project instances' do
10
+ project = double('PGit::Pivotal::Project')
11
+ allow(project).to receive(:hash=)
12
+ get_request = double('get_request')
13
+ api_token = 'some_api_token_123'
14
+ hashes_of_items = [{'name' => 'PGit', 'kind' => 'project' }]
15
+ allow(PGit::Pivotal::Project).to receive(:new).and_yield(project).and_return(project)
16
+ allow_any_instance_of(PGit::Pivotal::CollectionRequest).to receive(:api_token).and_return(api_token)
17
+ allow(JSON).to receive(:parse).with(get_request).and_return(hashes_of_items)
18
+
19
+ projects = PGit::Pivotal::Projects.new
20
+ allow(projects).to receive(:get_request).and_return(get_request)
21
+ instantiated_projects = projects.get!
22
+ expect(instantiated_projects).to include(project)
23
+ expect(projects.api_token).to eq api_token
24
+ end
25
+ end
26
+
27
+ describe 'with specific api_token' do
28
+ it 'should instantiate a bunch of PGit::Pivotal::Project instances only associated with the token' do
29
+ project = double('PGit::Pivotal::Project')
30
+ allow(project).to receive(:hash=)
31
+ get_request = double('get_request')
32
+ hashes_of_items = [{'name' => 'PGit', 'kind' => 'project' }]
33
+ allow(PGit::Pivotal::Project).to receive(:new).and_yield(project).and_return(project)
34
+ allow(JSON).to receive(:parse).with(get_request).and_return(hashes_of_items)
35
+
36
+ api_token = 'some_api_token_123'
37
+ projects = PGit::Pivotal::Projects.new(api_token: api_token)
38
+ expect(projects.api_token).to eq api_token
39
+ end
40
+ end
41
+
42
+ describe 'sublink' do
43
+ it 'should be "projects"' do
44
+ projects = PGit::Pivotal::Projects.new
45
+ expect(projects.sublink).to eq 'projects'
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,24 @@
1
+ require 'spec_helper'
2
+
3
+ describe PGit::Pivotal::Request::Query do
4
+ describe '#new(scope: :current_backlog)' do
5
+ it 'should generate the right query string ' do
6
+ query = PGit::Pivotal::Request::Query.new
7
+ expect("#{query}").to eq ''
8
+ end
9
+ end
10
+
11
+ describe '#new(scope: :current_backlog)' do
12
+ it 'should generate the right query string ' do
13
+ query = PGit::Pivotal::Request::Query.new(scope: :current_backlog)
14
+ expect("#{query}").to eq '?scope=current_backlog'
15
+ end
16
+ end
17
+
18
+ describe '#new(scope: :current_backlog, offset: 1)' do
19
+ it 'should generate the right query string ' do
20
+ query = PGit::Pivotal::Request::Query.new(scope: :current_backlog, offset: 1)
21
+ expect("#{query}").to eq '?scope=current_backlog&offset=1'
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,113 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'PGit::Pivotal::Story' do
4
+ describe '#get!' do
5
+ it 'should generate the story' do
6
+ story_id = '123'
7
+ current_project = double('current_project', id: '321', api_token: 'abc10xyz')
8
+ get_request = "curl -X GET -H 'X-TrackerToken: abc10xyz' https://www.pivotaltracker.com/services/v5/projects/321/stories/123"
9
+ fake_good_json = <<-GOOD_JSON
10
+ {
11
+ "created_at": "2014-11-25T12:00:00Z",
12
+ "current_state": "unstarted",
13
+ "description": "ignore the droids",
14
+ "estimate": 2,
15
+ "id": 555,
16
+ "kind": "story",
17
+ "labels": [],
18
+ "name": "Bring me the passengers",
19
+ "owner_ids": [],
20
+ "project_id": 99,
21
+ "requested_by_id": 101,
22
+ "story_type": "feature",
23
+ "updated_at": "2014-11-25T12:00:00Z",
24
+ "url": "http://localhost/story/show/555"
25
+ }
26
+ GOOD_JSON
27
+
28
+ allow(PGit::CurrentProject).to receive(:new).and_return(current_project)
29
+ story = PGit::Pivotal::Story.new(story_id)
30
+ allow(story).to receive(:`).with(get_request).and_return(fake_good_json)
31
+ allow_any_instance_of(PGit::Pivotal::IndividualRequest).to receive(:`).with(get_request).and_return(fake_good_json)
32
+ story.get!
33
+
34
+ expect(story.name).to eq "Bring me the passengers"
35
+ expect(story.description).to eq "ignore the droids"
36
+ end
37
+ end
38
+
39
+ describe '#put' do
40
+ it 'updates the story' do
41
+ story_id = '123'
42
+ current_project = double('current_project', id: '321', api_token: 'abc10xyz')
43
+ put_request = "curl -X PUT -H 'X-TrackerToken: abc10xyz' -H 'Content-Type: application/json' -d '{\"estimate\":3}' https://www.pivotaltracker.com/services/v5/projects/321/stories/123"
44
+ fake_good_json = <<-GOOD_JSON
45
+ {
46
+ "created_at": "2014-11-25T12:00:00Z",
47
+ "current_state": "unstarted",
48
+ "description": "ignore the droids",
49
+ "estimate": 2,
50
+ "id": 555,
51
+ "kind": "story",
52
+ "labels": [],
53
+ "name": "Bring me the passengers",
54
+ "owner_ids": [],
55
+ "project_id": 99,
56
+ "requested_by_id": 101,
57
+ "story_type": "feature",
58
+ "updated_at": "2014-11-25T12:00:00Z",
59
+ "url": "http://localhost/story/show/555"
60
+ }
61
+ GOOD_JSON
62
+
63
+
64
+ allow(PGit::CurrentProject).to receive(:new).and_return(current_project)
65
+ story = PGit::Pivotal::Story.new(story_id)
66
+ allow(story).to receive(:`)
67
+ story.estimate = 3
68
+ story.put!
69
+
70
+ expect(story).to have_received(:`).with(put_request)
71
+ end
72
+
73
+ describe 'with a story instantiated with a block' do
74
+ it 'should still update the story' do
75
+ story_id = '123'
76
+ current_project = double('current_project', id: '321', api_token: 'abc10xyz')
77
+ get_request = "curl -X GET -H 'X-TrackerToken: abc10xyz' https://www.pivotaltracker.com/services/v5/projects/321/stories/123"
78
+ put_request = "curl -X PUT -H 'X-TrackerToken: abc10xyz' -H 'Content-Type: application/json' -d '{\"estimate\":3,\"requested_by_id\":102}' https://www.pivotaltracker.com/services/v5/projects/321/stories/123"
79
+ fake_good_json = <<-GOOD_JSON
80
+ {
81
+ "created_at": "2014-11-25T12:00:00Z",
82
+ "current_state": "unstarted",
83
+ "description": "ignore the droids",
84
+ "estimate": 2,
85
+ "id": 123,
86
+ "kind": "story",
87
+ "labels": [],
88
+ "name": "Bring me the passengers",
89
+ "owner_ids": [],
90
+ "project_id": 321,
91
+ "requested_by_id": 101,
92
+ "story_type": "feature",
93
+ "updated_at": "2014-11-25T12:00:00Z",
94
+ "url": "http://localhost/story/show/555"
95
+ }
96
+ GOOD_JSON
97
+
98
+
99
+ allow(PGit::CurrentProject).to receive(:new).and_return(current_project)
100
+ story = PGit::Pivotal::Story.new(story_id)
101
+ allow(story).to receive(:`).with(get_request).and_return(fake_good_json)
102
+ allow(story).to receive(:`).with(put_request)
103
+ allow_any_instance_of(PGit::Pivotal::IndividualRequest).to receive(:`).with(get_request).and_return(fake_good_json)
104
+ story.get!
105
+ story.estimate = 3
106
+ story.requested_by_id = 102
107
+ story.put!
108
+
109
+ expect(story).to have_received(:`).with(put_request)
110
+ end
111
+ end
112
+ end
113
+ end
@@ -40,19 +40,19 @@ describe 'PGit::PivotalRequestValidator' do
40
40
 
41
41
  expect do
42
42
  PGit::PivotalRequestValidator.new(request)
43
- end.to raise_error(PGit::ExternalError)
43
+ end.to raise_error(PGit::Error::External)
44
44
  end
45
45
  end
46
46
 
47
47
  describe 'when the request has no "kind"' do
48
- it 'should raise a PGit::ExternalError' do
48
+ it 'should raise a PGit::Error::External' do
49
49
  request = <<-REQUEST
50
50
  some unrecognizable request
51
51
  REQUEST
52
52
 
53
53
  expect do
54
54
  PGit::PivotalRequestValidator.new(request)
55
- end.to raise_error(PGit::ExternalError)
55
+ end.to raise_error(PGit::Error::External)
56
56
  end
57
57
  end
58
58
 
@@ -0,0 +1,52 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'PGit::Project::Add' do
4
+ describe 'user is on a project path that already exists' do
5
+ it 'raises an error' do
6
+ app = instance_double('PGit::Project::Application',
7
+ exists?: true)
8
+ expect{PGit::Project::Add.new(app)}.to raise_error(PGit::Error::User, 'Project path already exists. See `pgit proj update --help.`')
9
+ end
10
+ end
11
+
12
+ describe '#execute!' do
13
+ it 'instantiates a project and saves it' do
14
+ class SomeProject
15
+ include ActiveModel::Validations
16
+ validates_with PGit::Validators::ProjectValidator
17
+ def get!
18
+ end
19
+
20
+ def kind
21
+ 'project'
22
+ end
23
+ end
24
+
25
+ project = SomeProject.new
26
+ config_project = instance_double('PGit::Project')
27
+ projects = [config_project]
28
+ app = instance_double('PGit::Project::Application',
29
+ exists?: false,
30
+ project: project,
31
+ projects: projects)
32
+ adder = instance_double('PGit::Project::InteractiveAdder',
33
+ execute!: nil,
34
+ project: project,
35
+ save!: nil)
36
+ reuse_adder = instance_double('PGit::Project::ReuseApiTokenAdder',
37
+ execute!: nil,
38
+ project: project)
39
+ allow(PGit::Project::InteractiveAdder).to receive(:new).with(project).and_return(adder)
40
+ allow(PGit::Project::ReuseApiTokenAdder).to receive(:new).with(project, projects).and_return(reuse_adder)
41
+ add = PGit::Project::Add.new(app)
42
+ allow(add).to receive(:puts).with("Successfully added the project!")
43
+
44
+ add.execute!
45
+
46
+ expect(reuse_adder).to have_received(:execute!)
47
+ expect(adder).to have_received(:execute!)
48
+ expect(adder).to have_received(:save!)
49
+ expect(add).to have_received(:puts).with("Successfully added the project!")
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,69 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'PGit::Project::Application' do
4
+ describe '#exists?' do
5
+ it 'delegates to @project' do
6
+ global_opts = {}
7
+ opts = { 'path' => '/some/path',
8
+ 'api_token' => 'someapitoken1234',
9
+ 'id' => 12345}
10
+ args = []
11
+ configuration = instance_double('PGit::Configuration')
12
+ allow(PGit::Configuration).to receive(:new).and_return(configuration)
13
+ project_exists = double('response')
14
+ allow_any_instance_of(PGit::Project).to receive(:exists?).and_return(project_exists)
15
+ app = PGit::Project::Application.new(global_opts, opts, args)
16
+
17
+ expect(app.exists?).to eq project_exists
18
+ end
19
+
20
+ it 'delegates to @project' do
21
+ global_opts = {}
22
+ opts = { 'path' => '/some/path',
23
+ 'api_token' => 'someapitoken1234',
24
+ 'id' => 12345}
25
+ args = []
26
+ configuration = instance_double('PGit::Configuration')
27
+ allow(PGit::Configuration).to receive(:new).and_return(configuration)
28
+ project_save = double('response')
29
+ allow_any_instance_of(PGit::Project).to receive(:save!).and_return(project_save)
30
+ app = PGit::Project::Application.new(global_opts, opts, args)
31
+
32
+ expect(app.save!).to eq project_save
33
+ end
34
+ end
35
+
36
+ describe '#project' do
37
+ it 'returns the project' do
38
+ global_opts = {}
39
+ opts = { 'path' => '/some/path',
40
+ 'api_token' => 'someapitoken1234',
41
+ 'id' => 12345}
42
+ args = []
43
+ proj = instance_double('PGit::Project')
44
+ allow(PGit::Project).to receive(:new).and_return(proj)
45
+
46
+ app = PGit::Project::Application.new(global_opts, opts, args)
47
+ expect(app.project).to eq proj
48
+ end
49
+ end
50
+
51
+ describe '#projects' do
52
+ it 'returns the projects' do
53
+ global_opts = {}
54
+ opts = { 'path' => '/some/path',
55
+ 'api_token' => 'someapitoken1234',
56
+ 'id' => 12345}
57
+ args = []
58
+ proj = instance_double('PGit::Project')
59
+ projects = instance_double('Array')
60
+ config = instance_double('PGit::Configuration', projects: projects)
61
+ allow(PGit::Configuration).to receive(:new).and_return(config)
62
+ allow(PGit::Project).to receive(:new).and_return(proj)
63
+
64
+ app = PGit::Project::Application.new(global_opts, opts, args)
65
+ expect(app.projects).to eq projects
66
+ end
67
+ end
68
+ end
69
+
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'byebug'
3
+
4
+ describe 'PGit::Project::InteractiveAdder.new(proj)' do
5
+ describe 'api_token does not exist' do
6
+ it 'asks what the api token associated for the project is' do
7
+ question = "What's the project api_token?"
8
+ api_token = 'SOMEAPITOKEN'
9
+ id_1 = 123
10
+ id_2 = 127
11
+ project = instance_double('PGit::Project',
12
+ defaulted_attrs: [:api_token],
13
+ :id= => true)
14
+
15
+ def project.api_token
16
+ @api_token
17
+ end
18
+
19
+ def project.api_token=(some_api_token)
20
+ @api_token = some_api_token
21
+ end
22
+
23
+ project.api_token = :no_api_token_given
24
+
25
+ allow_any_instance_of(PGit::Project::InteractiveAdder).to receive(:puts).with(question)
26
+ response = instance_double('String', chomp: api_token)
27
+ allow(STDIN).to receive(:gets).and_return(response, '0')
28
+ pivotal_project_1 = double('PGit::Pivotal::Project', name: 'Some Project Name 1',
29
+ id: id_1)
30
+ pivotal_project_2 = double('PGit::Pivotal::Project', name: 'Some Project Name 2',
31
+ id: id_2)
32
+ instantiated_projects = [pivotal_project_1, pivotal_project_2]
33
+ projects = double('PGit::Pivotal::Projects')
34
+ allow(projects).to receive(:get!).and_return(instantiated_projects)
35
+ allow(PGit::Pivotal::Projects).to receive(:new).with(api_token: api_token).
36
+ and_return(projects)
37
+ adder = PGit::Project::InteractiveAdder.new(project)
38
+ adder.execute!
39
+
40
+ expect(adder).to have_received(:puts).with(question)
41
+ expect(project.api_token).to eq api_token
42
+ expect(project).to have_received(:id=).with(id_1)
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,86 @@
1
+ require 'spec_helper'
2
+
3
+ describe 'PGit::Project::Remove' do
4
+ describe '#execute' do
5
+ describe 'project path matches a project path in the configuration' do
6
+ describe 'user answers yes' do
7
+ it 'should remove the project' do
8
+ path = 'some/path'
9
+ common_path = 'some/path'
10
+ project = instance_double('PGit::Project', path: common_path, exists?: true)
11
+ config_project_1 = instance_double('PGit::Project', path: common_path)
12
+ config_project_2 = instance_double('PGit::Project', path: 'some/other/path')
13
+ projects = [config_project_1, config_project_2]
14
+ app = instance_double('PGit::Project::Application', project: project, projects: projects)
15
+ rm = PGit::Project::Remove.new(app)
16
+ question = "Are you sure you want to remove #{path} from the configuration file?"
17
+ config = double('config', :question= => nil, :options= => nil)
18
+ confirmation_question = instance_double('Interactive::Question')
19
+ options = [:yes, :no]
20
+ response = double('response', yes?: true)
21
+ allow(Interactive::Question).to receive(:new).and_yield(config).and_return(confirmation_question)
22
+ allow(config).to receive(:question).with(question)
23
+ allow(config).to receive(:options).with(options)
24
+ allow(confirmation_question).to receive(:ask_and_wait_for_valid_response).and_yield(response)
25
+ allow(rm).to receive(:puts)
26
+ allow(project).to receive(:remove!)
27
+
28
+ rm.execute!
29
+ expect(Interactive::Question).to have_received(:new)
30
+ expect(config).to have_received(:question=).with(question)
31
+ expect(config).to have_received(:options=).with(options)
32
+ expect(confirmation_question).to have_received(:ask_and_wait_for_valid_response)
33
+ expect(rm).to have_received(:puts).with("Removing #{path} from the configuration file...")
34
+ expect(rm).to have_received(:puts).with("Removed.")
35
+ expect(project).to have_received(:remove!)
36
+ end
37
+ end
38
+
39
+ describe 'user answers no' do
40
+ it 'should respond with "Canceling..."' do
41
+ path = 'some/path'
42
+ common_path = 'some/path'
43
+ project = instance_double('PGit::Project', path: common_path, exists?: true)
44
+ config_project_1 = instance_double('PGit::Project', path: common_path)
45
+ config_project_2 = instance_double('PGit::Project', path: 'some/other/path')
46
+ projects = [config_project_1, config_project_2]
47
+ app = instance_double('PGit::Project::Application', project: project, projects: projects)
48
+ rm = PGit::Project::Remove.new(app)
49
+ question = "Are you sure you want to remove #{path} from the configuration file?"
50
+ config = double('config', :question= => nil, :options= => nil)
51
+ confirmation_question = instance_double('Interactive::Question')
52
+ options = [:yes, :no]
53
+ response = double('response', yes?: false, no?: true)
54
+ allow(Interactive::Question).to receive(:new).and_yield(config).and_return(confirmation_question)
55
+ allow(config).to receive(:question).with(question)
56
+ allow(config).to receive(:options).with(options)
57
+ allow(confirmation_question).to receive(:ask_and_wait_for_valid_response).and_yield(response)
58
+ allow(rm).to receive(:puts)
59
+ allow(project).to receive(:remove!)
60
+
61
+ rm.execute!
62
+ expect(Interactive::Question).to have_received(:new)
63
+ expect(config).to have_received(:question=).with(question)
64
+ expect(config).to have_received(:options=).with(options)
65
+ expect(confirmation_question).to have_received(:ask_and_wait_for_valid_response)
66
+ expect(rm).to have_received(:puts).with("Cancelling...")
67
+ expect(rm).not_to have_received(:puts).with("Removing #{path} from the configuration file...")
68
+ expect(project).not_to have_received(:remove!)
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ describe 'project path does not match a project path in the configuration' do
75
+ it 'raises an error' do
76
+ path = 'some/path'
77
+ some_path_not_in_config = 'some/path/not/in/config'
78
+ project = instance_double('PGit::Project', path: some_path_not_in_config, exists?: false)
79
+ config_project_1 = instance_double('PGit::Project', path: path)
80
+ config_project_2 = instance_double('PGit::Project', path: 'some/other/path')
81
+ projects = [config_project_1, config_project_2]
82
+ app = instance_double('PGit::Project::Application', project: project, projects: projects)
83
+ expect{PGit::Project::Remove.new(app)}.to raise_error(PGit::Error::User, "#{some_path_not_in_config} is not in the configuration file.")
84
+ end
85
+ end
86
+ end