git_pivotal_tracker 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,4 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ test.txt
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- git-tracker
1
+ git_pivotal_tracker
2
2
  ===========
3
3
 
4
4
  Inspired by [Hashrocket's blend of git and Pivotal Tracker](http://reinh.com/blog/2009/03/02/a-git-workflow-for-agile-teams.html) and [Carbon Five's article on effective git workflows](http://blog.carbonfive.com/2010/11/01/integrating-topic-branches-in-git/) and [the git-pivotal gem](https://github.com/trydionel/git-pivotal), I wanted a tool that makes the git workflow fun and simple.
@@ -18,7 +18,7 @@ These commands collect the first available story from your Pivotal Tracker proje
18
18
 
19
19
  * `git-finish`
20
20
 
21
- When on a topic branch, this command will fetch the latest integration branch ('master' by default), rebase your topic branch from it, merge the branch into the integration branch with no-fast-forword and push the integration branch to origin.
21
+ When on a topic branch, this command will fetch the latest integration branch ('master' by default), rebase your topic branch from it, merge the branch into the integration branch with no-fast-forward and push the integration branch to origin.
22
22
 
23
23
  * `git-info`
24
24
 
@@ -49,9 +49,13 @@ The project id is best placed within your project's git config:
49
49
 
50
50
  ``git config -f .git/config pivotal.project-id 88888``
51
51
 
52
+ If you project's access is setup to use HTTPS:
53
+
54
+ ``git config -f .git/config pivotal.use-ssl 1``
55
+
52
56
  If you prefer to merge back to a branch other than master when you've finished a story, you can configure that:
53
57
 
54
- ``git config --global pivotal.integration-branch develop``
58
+ ``git config -f .git/config pivotal.integration-branch develop``
55
59
 
56
60
  If you prefer to fetch and rebase from origin before merging (default is no):
57
61
 
@@ -17,6 +17,7 @@ Gem::Specification.new do |s|
17
17
  s.required_rubygems_version = ">= 1.3.6"
18
18
 
19
19
  s.add_development_dependency "rspec"
20
+ s.add_development_dependency "webmock"
20
21
  s.add_runtime_dependency "grit"
21
22
  s.add_runtime_dependency "pivotal-tracker"
22
23
 
@@ -33,6 +33,8 @@ module GitPivotalTracker
33
33
  end
34
34
 
35
35
  PivotalTracker::Client.token = options[:api_token]
36
+ PivotalTracker::Client.use_ssl = options[:use_ssl]
37
+
36
38
  nil
37
39
  end
38
40
 
@@ -47,7 +49,9 @@ module GitPivotalTracker
47
49
  end
48
50
 
49
51
  def story_id
50
- @story_id ||= current_branch[/\d+/].to_i
52
+ if current_branch =~ /-(\d+)-/
53
+ $1
54
+ end
51
55
  end
52
56
 
53
57
  def project
@@ -72,18 +76,21 @@ module GitPivotalTracker
72
76
  options[:rebase] = repository.config['pivotal.rebase']
73
77
  options[:full_name] = repository.config['pivotal.full-name'] || repository.config['user.name']
74
78
  options[:verbose] = repository.config['pivotal.verbose']
79
+ options[:use_ssl] = repository.config['pivotal.use-ssl']
75
80
  end
76
81
 
77
82
  def parse_argv(*args)
78
83
  OptionParser.new do |opts|
79
84
  opts.banner = "Usage: git <feature|chore|bug> [options]"
80
- opts.on("-k", "--api-key=", "Pivotal Tracker API key") { |k| options[:api_token] = k }
85
+ opts.on("-t", "--api-token=", "Pivotal Tracker API key") { |k| options[:api_token] = k }
81
86
  opts.on("-p", "--project-id=", "Pivotal Tracker project id") { |p| options[:project_id] = p }
82
87
  opts.on("-b", "--integration-branch=", "The branch to merge finished stories back down onto") { |b| options[:integration_branch] = b }
83
- opts.on("-f", "--fast-forward=", "Merge topic branch with fast forward") { |f| options[:fast_foward] = f }
84
88
  opts.on("-n", "--full-name=", "Your Pivotal Tracker full name") { |n| options[:full_name] = n }
85
- opts.on("-r", "--rebase=", "Fetch and rebase the integration branch before merging") { |r| options[:rebase] = r }
86
- opts.on("-v", "--verbose=", "Verbose command logging") { |v| options[:verbose] = v }
89
+
90
+ opts.on("-F", "--fast-forward", "Merge topic branch with fast forward") { |f| options[:fast_forward] = f }
91
+ opts.on("-S", "--use-ssl", "Use SSL for connection to Pivotal Tracker") { |s| options[:use_ssl] = s }
92
+ opts.on("-R", "--rebase", "Fetch and rebase the integration branch before merging") { |r| options[:rebase] = r }
93
+ opts.on("-V", "--verbose", "Verbose command logging") { |v| options[:verbose] = v }
87
94
  opts.on_tail("-h", "--help", "This usage guide") { put opts.to_s; exit 0 }
88
95
  end.parse!(args)
89
96
  end
@@ -5,24 +5,25 @@ module GitPivotalTracker
5
5
  return 1 if super
6
6
 
7
7
  unless story_id
8
- put "Branch name must contain a Pivotal Tracker story id"
8
+ puts "Branch name must contain a Pivotal Tracker story id"
9
9
  return 1
10
10
  end
11
11
 
12
12
  if options[:rebase]
13
13
  puts "Fetching origin and rebasing #{current_branch}"
14
- log repository.git.fetch({:raise => true}, "origin")
15
- log repository.git.rebase({:raise => true}, "origin/#{integration_branch}")
14
+ log repository.git.pull({:raise => true})
15
+ log repository.git.rebase({:raise => true}, integration_branch)
16
16
  end
17
17
 
18
18
  puts "Merging #{current_branch} into #{integration_branch}"
19
19
  log repository.git.checkout({:raise => true}, integration_branch)
20
20
 
21
- flags = options[:fast_forward] ? {} : {:'no-ff' => true}
22
- log repository.git.merge({:raise => true}.merge(flags), current_branch)
21
+ merge_options = {:raise => true}
22
+ merge_options[:no_ff] = true unless options[:fast_forward]
23
+ log repository.git.merge(merge_options, current_branch)
23
24
 
24
- puts "Pushing #{integration_branch} to origin"
25
- log repository.git.push({:raise => true}, "origin", integration_branch)
25
+ puts "Pushing #{integration_branch}"
26
+ log repository.git.push({:raise => true})
26
27
 
27
28
  puts "Marking Story #{story_id} as finished..."
28
29
  if story.update(:current_state => finished_state)
@@ -24,7 +24,7 @@ module GitPivotalTracker
24
24
  log repository.git.checkout({:b => true, :raise => true}, branch)
25
25
 
26
26
  puts "Updating #{type} status in Pivotal Tracker..."
27
- if story.update(:owned_by => options[:name], :current_state => :started)
27
+ if story.update(:owned_by => options[:full_name], :current_state => :started)
28
28
  puts "Success"
29
29
  return 0
30
30
  else
@@ -33,15 +33,14 @@ module GitPivotalTracker
33
33
  end
34
34
  end
35
35
 
36
- private
37
-
38
36
  def type
39
37
  self.class.name.downcase.split(/::/).last
40
38
  end
41
39
 
40
+ private
41
+
42
42
  def fetch_story
43
- # TODO: check for rejected stories as well
44
- conditions = { :current_state => "unstarted", :limit => 1, :offset => 0 }
43
+ conditions = { :current_state => "unstarted", :limit => 1 }
45
44
  conditions[:story_type] = type unless type == 'story'
46
45
  project.stories.all(conditions).first
47
46
  end
@@ -1,3 +1,3 @@
1
1
  module GitPivotalTracker
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0"?>
2
+ <story>
3
+ <name>Pause the film</name>
4
+ <description>As a moderator,
5
+ I can pause the film
6
+ In order to allow another activity to take place (discussion, etc).</description>
7
+ <story_type>feature</story_type>
8
+ <estimate>2</estimate>
9
+ <current_state>finished</current_state>
10
+ <requested_by>Ben Lindsey</requested_by>
11
+ <owned_by>Ben Lindsey</owned_by>
12
+ <labels>moderate,2_needs_design</labels>
13
+ <project_id>123</project_id>
14
+ <other_id></other_id>
15
+ <integration_id></integration_id>
16
+ <created_at>2011-07-14T23:06:28+00:00</created_at>
17
+ </story>
@@ -0,0 +1,3 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <stories type="array" count="0" total="2" limit="0">
3
+ </stories>
@@ -0,0 +1,19 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <stories type="array" count="1" total="2" limit="1">
3
+ <story>
4
+ <id type="integer">1234567890</id>
5
+ <project_id type="integer">123</project_id>
6
+ <story_type>feature</story_type>
7
+ <url>http://www.pivotaltracker.com/story/show/1234567890</url>
8
+ <estimate type="integer">2</estimate>
9
+ <current_state>unstarted</current_state>
10
+ <description>As a moderator,
11
+ I can pause the film
12
+ In order to allow another activity to take place (discussion, etc).</description>
13
+ <name>Pause the film</name>
14
+ <requested_by>Ben Lindsey</requested_by>
15
+ <created_at type="datetime">2011/07/14 23:06:28 UTC</created_at>
16
+ <updated_at type="datetime">2011/07/14 23:13:24 UTC</updated_at>
17
+ <labels>moderate,2_needs_design</labels>
18
+ </story>
19
+ </stories>
@@ -0,0 +1,37 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project>
3
+ <id>123</id>
4
+ <name>Test Project</name>
5
+ <iteration_length type="integer">1</iteration_length>
6
+ <week_start_day>Monday</week_start_day>
7
+ <point_scale>0,1,2,3,5,8</point_scale>
8
+ <account>Carbon Five</account>
9
+ <start_date type="date">2011/07/18</start_date>
10
+ <first_iteration_start_time type="datetime">2011/07/18 07:00:00 UTC</first_iteration_start_time>
11
+ <current_iteration_number type="integer">1</current_iteration_number>
12
+ <enable_tasks type="boolean">true</enable_tasks>
13
+ <velocity_scheme>Average of 3 iterations</velocity_scheme>
14
+ <current_velocity>10</current_velocity>
15
+ <initial_velocity>10</initial_velocity>
16
+ <number_of_done_iterations_to_show>12</number_of_done_iterations_to_show>
17
+ <labels>1_needs_definition,2_needs_design,discuss,moderate</labels>
18
+ <last_activity_at type="datetime">2011/07/14 23:16:29 UTC</last_activity_at>
19
+ <allow_attachments>true</allow_attachments>
20
+ <public>false</public>
21
+ <use_https>false</use_https>
22
+ <bugs_and_chores_are_estimatable>false</bugs_and_chores_are_estimatable>
23
+ <commit_mode>false</commit_mode>
24
+ <memberships type="array">
25
+ <membership>
26
+ <id>1058581</id>
27
+ <person>
28
+ <email>ben@carbonfive.com</email>
29
+ <name>Ben Lindsey</name>
30
+ <initials>BL</initials>
31
+ </person>
32
+ <role>Owner</role>
33
+ </membership>
34
+ </memberships>
35
+ <integrations type="array">
36
+ </integrations>
37
+ </project>
@@ -0,0 +1,17 @@
1
+ <?xml version="1.0"?>
2
+ <story>
3
+ <name>Pause the film</name>
4
+ <description>As a moderator,
5
+ I can pause the film
6
+ In order to allow another activity to take place (discussion, etc).</description>
7
+ <story_type>feature</story_type>
8
+ <estimate>2</estimate>
9
+ <current_state>started</current_state>
10
+ <requested_by>Ben Lindsey</requested_by>
11
+ <owned_by>Ben Lindsey</owned_by>
12
+ <labels>moderate,2_needs_design</labels>
13
+ <project_id>123</project_id>
14
+ <other_id></other_id>
15
+ <integration_id></integration_id>
16
+ <created_at>2011-07-14T23:06:28+00:00</created_at>
17
+ </story>
@@ -0,0 +1,18 @@
1
+ <?xml version="1.0"?>
2
+ <story>
3
+ <id>1234567890</id>
4
+ <name>Pause the film</name>
5
+ <description>As a moderator,
6
+ I can pause the film
7
+ In order to allow another activity to take place (discussion, etc).</description>
8
+ <story_type>feature</story_type>
9
+ <estimate>2</estimate>
10
+ <current_state>started</current_state>
11
+ <requested_by>Ben Lindsey</requested_by>
12
+ <owned_by>Ben Lindsey</owned_by>
13
+ <labels>moderate,2_needs_design</labels>
14
+ <project_id>123</project_id>
15
+ <other_id></other_id>
16
+ <integration_id></integration_id>
17
+ <created_at>2011-07-14T23:06:28+00:00</created_at>
18
+ </story>
@@ -0,0 +1,196 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe GitPivotalTracker::Base do
4
+ describe "#parse_argv" do
5
+
6
+ context "by default" do
7
+ before do
8
+ stub_git_config
9
+ subject = GitPivotalTracker::Base.new
10
+ end
11
+
12
+ it "leaves integration_branch nil" do
13
+ subject.options[:integration_branch].should be_nil
14
+ end
15
+
16
+ it "leaves fast_forward nil" do
17
+ subject.options[:fast_forward].should be_nil
18
+ end
19
+
20
+ it "leaves rebase nil" do
21
+ subject.options[:rebase].should be_nil
22
+ end
23
+
24
+ it "leaves verbose nil" do
25
+ subject.options[:verbose].should be_nil
26
+ end
27
+
28
+ it "leaves use_ssl nil" do
29
+ subject.options[:use_ssl].should be_nil
30
+ end
31
+
32
+ it "leaves full_name nil" do
33
+ subject.options[:full_name].should be_nil
34
+ end
35
+ end
36
+
37
+ it "sets the api_token" do
38
+ GitPivotalTracker::Base.new("--api-token", "8a8a8a8").options[:api_token].should == '8a8a8a8'
39
+ GitPivotalTracker::Base.new("-t", "8a8a8a8").options[:api_token].should == '8a8a8a8'
40
+ end
41
+
42
+ it "sets the project_id" do
43
+ GitPivotalTracker::Base.new("--project-id", "123").options[:project_id].should == '123'
44
+ GitPivotalTracker::Base.new("-p", "123").options[:project_id].should == '123'
45
+ end
46
+
47
+ it "sets the integration_branch" do
48
+ GitPivotalTracker::Base.new("--integration-branch", "development").options[:integration_branch].should == 'development'
49
+ GitPivotalTracker::Base.new("-b", "development").options[:integration_branch].should == 'development'
50
+ end
51
+
52
+ it "sets full_name" do
53
+ GitPivotalTracker::Base.new("--full-name", "Full Name").options[:full_name].should == 'Full Name'
54
+ GitPivotalTracker::Base.new("-n", "Full Name").options[:full_name].should == 'Full Name'
55
+ end
56
+
57
+ it "sets fast_forward" do
58
+ GitPivotalTracker::Base.new("--fast-forward").options[:fast_forward].should be
59
+ GitPivotalTracker::Base.new("-F").options[:fast_forward].should be
60
+ end
61
+
62
+ it "sets use_ssl" do
63
+ GitPivotalTracker::Base.new("--use-ssl").options[:use_ssl].should be
64
+ GitPivotalTracker::Base.new("-S").options[:use_ssl].should be
65
+ end
66
+
67
+ it "sets rebase" do
68
+ GitPivotalTracker::Base.new("--rebase").options[:rebase].should be
69
+ GitPivotalTracker::Base.new("-R").options[:rebase].should be
70
+ end
71
+
72
+ it "sets verbose" do
73
+ GitPivotalTracker::Base.new("--verbose").options[:verbose].should be
74
+ GitPivotalTracker::Base.new("-V").options[:verbose].should be
75
+ end
76
+ end
77
+
78
+ describe "#parse_gitconfig" do
79
+ context "with a full-name" do
80
+ before do
81
+ stub_git_config 'pivotal.full-name' => 'Full Name', 'user.name' => 'User Name'
82
+ subject = GitPivotalTracker::Base.new
83
+ end
84
+
85
+ it "sets the full_name to the full name" do
86
+ subject.options[:full_name].should == 'Full Name'
87
+ end
88
+ end
89
+
90
+ context "with no full-name" do
91
+ before do
92
+ stub_git_config({
93
+ 'user.name' => 'User Name',
94
+ 'pivotal.integration-branch' => 'development',
95
+ 'pivotal.fast-forward' => 1,
96
+ 'pivotal.rebase' => 1,
97
+ 'pivotal.verbose' => 1,
98
+ 'pivotal.use-ssl' => 1
99
+ })
100
+ subject = GitPivotalTracker::Base.new
101
+ end
102
+
103
+ it "sets use_ssl" do
104
+ subject.options[:use_ssl].should be
105
+ end
106
+
107
+ it "sets the api_token" do
108
+ subject.options[:api_token].should == '8a8a8a8'
109
+ end
110
+
111
+ it "sets the project_id" do
112
+ subject.options[:project_id].should == '123'
113
+ end
114
+
115
+ it "sets fast_forward" do
116
+ subject.options[:fast_forward].should be
117
+ end
118
+
119
+ it "sets rebase" do
120
+ subject.options[:rebase].should be
121
+ end
122
+
123
+ it "sets verbose" do
124
+ subject.options[:verbose].should be
125
+ end
126
+
127
+ it "sets the full_name to the user name" do
128
+ subject.options[:full_name].should == 'User Name'
129
+ end
130
+ end
131
+ end
132
+
133
+ describe ".new" do
134
+ context "given an invalid git root" do
135
+ before do
136
+ @current_dir = Dir.pwd
137
+ Dir.chdir("/")
138
+ end
139
+
140
+ it "fails to initialize" do
141
+ expect { GitPivotalTracker::Base.new }.to raise_error "No .git directory found"
142
+ end
143
+
144
+ after do
145
+ Dir.chdir @current_dir
146
+ end
147
+ end
148
+
149
+ context "given no prepare-commit-msg hook" do
150
+ before do
151
+ File.delete ".git/hooks/prepare-commit-msg"
152
+ GitPivotalTracker::Base.new
153
+ end
154
+
155
+ it "installs the hook" do
156
+ File.executable?(".git/hooks/prepare-commit-msg").should be
157
+ end
158
+ end
159
+ end
160
+
161
+ describe "#run!" do
162
+ context "given a config with an api token and a project id" do
163
+ before do
164
+ stub_git_config
165
+ subject = GitPivotalTracker::Base.new
166
+ PivotalTracker::Client.should_receive(:token=).with('8a8a8a8')
167
+ end
168
+
169
+ it "succeeds" do
170
+ subject.run!.should be_nil
171
+ end
172
+ end
173
+
174
+ context "given the config has no api token" do
175
+ before do
176
+ stub_git_config 'pivotal.api-token' => nil
177
+ subject = GitPivotalTracker::Base.new
178
+ end
179
+
180
+ it "fails" do
181
+ subject.run!.should == 1
182
+ end
183
+ end
184
+
185
+ context "given the config has no project id" do
186
+ before do
187
+ stub_git_config 'pivotal.project-id' => nil
188
+ subject = GitPivotalTracker::Base.new
189
+ end
190
+
191
+ it "fails" do
192
+ subject.run!.should == 1
193
+ end
194
+ end
195
+ end
196
+ end
@@ -0,0 +1,84 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe GitPivotalTracker::Finish do
4
+
5
+ before do
6
+ stub_request(:get, 'http://www.pivotaltracker.com/services/v3/projects/123').
7
+ to_return :body => File.read("#{FIXTURES_PATH}/project.xml")
8
+ stub_request(:get, 'http://www.pivotaltracker.com/services/v3/projects/123/stories/1234567890').
9
+ to_return :body => File.read("#{FIXTURES_PATH}/story.xml")
10
+ @current_head = finish.repository.head
11
+ end
12
+
13
+ after do
14
+ puts finish.repository.git.checkout({}, @current_head.name)
15
+ puts finish.repository.git.reset({}, @current_head.commit.sha)
16
+ end
17
+
18
+ let(:finish) { GitPivotalTracker::Finish.new("-t", "8a8a8a8", "-p", "123") }
19
+
20
+ context "given I am not on a topic branch" do
21
+ before do
22
+ @new_branch = 'invalid-topic-branch'
23
+ finish.repository.git.branch({:D => true}, @new_branch)
24
+ finish.repository.git.checkout({:b => true, :raise => true}, @new_branch)
25
+ end
26
+
27
+ it "fails" do
28
+ finish.run!.should == 1
29
+ end
30
+ end
31
+
32
+ context "given I am on a topic branch with a commit" do
33
+ before do
34
+ finish.options[:integration_branch] = @current_head.name
35
+
36
+ finish_xml = File.read("#{FIXTURES_PATH}/finish_story.xml")
37
+ stub_request(:put, 'http://www.pivotaltracker.com/services/v3/projects/123/stories/1234567890').
38
+ with(:body => finish_xml).to_return(:body => finish_xml)
39
+
40
+ @repo = finish.repository
41
+ @new_branch = "testing-1234567890-branch_name"
42
+ @repo.git.branch({:D => true}, @new_branch)
43
+ @repo.git.checkout({:b => true, :raise => true}, @new_branch)
44
+
45
+ index = @repo.index
46
+ index.read_tree @new_branch
47
+ message = "Test commit: #{rand()}"
48
+ index.add('test.txt', message)
49
+ @sha = index.commit(message, [@repo.heads.detect { |h| h.name == @new_branch }.commit], nil, nil, @new_branch)
50
+
51
+ @repo.git.should_receive(:push).with(:raise => true)
52
+ end
53
+
54
+ it "merges the topic branch into the integration branch with a merge commit" do
55
+ finish.run!.should == 0
56
+ @repo.head.name.should == @current_head.branch
57
+ @repo.commits.first.parents.should have(2).items
58
+ @repo.heads.detect { |h| h.name == @current_head.name }.commit.sha.should == @sha
59
+ end
60
+
61
+ context "when I have rebase turned on" do
62
+ before do
63
+ finish.options[:rebase] = 1
64
+ finish.repository.git.should_receive(:pull).with(:raise => true)
65
+ finish.repository.git.should_receive(:rebase).with({:raise => true}, @current_head.name)
66
+ end
67
+
68
+ it "succeeds" do
69
+ finish.run!.should == 0
70
+ end
71
+ end
72
+
73
+ context "when I have fast forward turned on" do
74
+ before do
75
+ finish.options[:fast_forward] = 1
76
+ end
77
+
78
+ it "merges the topic branch without a merge commit" do
79
+ finish.run!.should == 0
80
+ @repo.heads.detect { |h| h.name == @current_head.name }.commit.sha.should == @sha
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,99 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'spec_helper')
2
+
3
+ describe GitPivotalTracker::Story do
4
+ describe "#run!" do
5
+ before do
6
+ stub_request(:get, 'http://www.pivotaltracker.com/services/v3/projects/123').
7
+ to_return :body => File.read("#{FIXTURES_PATH}/project.xml")
8
+ end
9
+
10
+ let(:story) { GitPivotalTracker::Story.new("-t", "8a8a8a8", "-p", "123") }
11
+
12
+ context "given there are no stories" do
13
+ before do
14
+ stub_request(:get, 'http://www.pivotaltracker.com/services/v3/projects/123/stories?filter=current_state:unstarted&limit=1').
15
+ to_return :body => File.read("#{FIXTURES_PATH}/no_stories.xml")
16
+ end
17
+
18
+ it "fails" do
19
+ story.run!.should == 1
20
+ end
21
+ end
22
+
23
+ context "given there is a story" do
24
+ before do
25
+ start_xml = File.read("#{FIXTURES_PATH}/start_story.xml")
26
+ stub_request(:get, 'http://www.pivotaltracker.com/services/v3/projects/123/stories?filter=current_state:unstarted&limit=1').
27
+ to_return :body => File.read("#{FIXTURES_PATH}/one_story.xml")
28
+ stub_request(:put, 'http://www.pivotaltracker.com/services/v3/projects/123/stories/1234567890').
29
+ with(:body => start_xml).to_return(:body => start_xml)
30
+
31
+ @current_branch = story.repository.head.name
32
+ end
33
+
34
+ context "then I accept the default branch suffix" do
35
+ before do
36
+ @expected_branch = 'feature-1234567890-pause_the_film'
37
+ story.repository.git.branch({:D => true}, @expected_branch)
38
+
39
+ story.should_receive(:gets).and_return "\n"
40
+ story.run!
41
+ end
42
+
43
+ it "creates a new branch" do
44
+ story.repository.head.name.should == @expected_branch
45
+ end
46
+ end
47
+
48
+ context "then I customize the branch suffix" do
49
+ before do
50
+ @expected_branch = 'feature-1234567890-new_name'
51
+ story.repository.git.branch({:D => true}, @expected_branch)
52
+
53
+ story.should_receive(:gets).and_return "new_name\n"
54
+ story.run!
55
+ end
56
+
57
+ it "creates a new branch" do
58
+ story.repository.head.name.should == @expected_branch
59
+ end
60
+ end
61
+
62
+ after do
63
+ story.repository.git.checkout({:raise => true}, @current_branch)
64
+ end
65
+ end
66
+
67
+ end
68
+
69
+ describe "#type" do
70
+ it "is a story" do
71
+ GitPivotalTracker::Story.new.type.should == 'story'
72
+ end
73
+ end
74
+ end
75
+
76
+ describe GitPivotalTracker::Bug do
77
+ describe "#type" do
78
+ it "is a bug" do
79
+ GitPivotalTracker::Bug.new.type.should == 'bug'
80
+ end
81
+ end
82
+ end
83
+
84
+ describe GitPivotalTracker::Feature do
85
+ describe "#type" do
86
+ it "is a feature" do
87
+ GitPivotalTracker::Feature.new.type.should == 'feature'
88
+ end
89
+ end
90
+ end
91
+
92
+ describe GitPivotalTracker::Chore do
93
+ describe "#type" do
94
+ it "is a chore" do
95
+ GitPivotalTracker::Chore.new.type.should == 'chore'
96
+ end
97
+ end
98
+ end
99
+
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,13 @@
1
- require File.expand_path(File.join(File.dirname(__FILE__), %w[.. lib git_pivotal_tracker]))
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
2
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
3
 
3
- Spec::Runner.configure do |config|
4
+ require 'git_pivotal_tracker'
5
+ require 'rspec'
6
+ require 'webmock/rspec'
7
+
8
+ FIXTURES_PATH = File.join(File.dirname(__FILE__), 'fixtures')
9
+
10
+ RSpec.configure do |config|
4
11
  # == Mock Framework
5
12
  #
6
13
  # RSpec uses it's own mocking framework by default. If you prefer to
@@ -10,3 +17,11 @@ Spec::Runner.configure do |config|
10
17
  # config.mock_with :flexmock
11
18
  # config.mock_with :rr
12
19
  end
20
+
21
+ def stub_git_config(opts = {})
22
+ git_options = {
23
+ "pivotal.api-token" => "8a8a8a8",
24
+ "pivotal.project-id" => "123"
25
+ }.merge opts
26
+ Grit::Repo.stub!(:new).and_return mock('Grit::Repo', :config => git_options)
27
+ end
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: git_pivotal_tracker
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.2
5
+ version: 0.0.3
6
6
  platform: ruby
7
7
  authors:
8
8
  - Ben Lindsey
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-14 00:00:00 -07:00
13
+ date: 2011-07-17 00:00:00 -07:00
14
14
  default_executable:
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
@@ -25,7 +25,7 @@ dependencies:
25
25
  type: :development
26
26
  version_requirements: *id001
27
27
  - !ruby/object:Gem::Dependency
28
- name: grit
28
+ name: webmock
29
29
  prerelease: false
30
30
  requirement: &id002 !ruby/object:Gem::Requirement
31
31
  none: false
@@ -33,10 +33,10 @@ dependencies:
33
33
  - - ">="
34
34
  - !ruby/object:Gem::Version
35
35
  version: "0"
36
- type: :runtime
36
+ type: :development
37
37
  version_requirements: *id002
38
38
  - !ruby/object:Gem::Dependency
39
- name: pivotal-tracker
39
+ name: grit
40
40
  prerelease: false
41
41
  requirement: &id003 !ruby/object:Gem::Requirement
42
42
  none: false
@@ -46,6 +46,17 @@ dependencies:
46
46
  version: "0"
47
47
  type: :runtime
48
48
  version_requirements: *id003
49
+ - !ruby/object:Gem::Dependency
50
+ name: pivotal-tracker
51
+ prerelease: false
52
+ requirement: &id004 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ version: "0"
58
+ type: :runtime
59
+ version_requirements: *id004
49
60
  description: provides a set of git workflow tools to start and finish Pivotal Tracker stories in topic branches
50
61
  email:
51
62
  - ben@carbonfive.com
@@ -82,7 +93,15 @@ files:
82
93
  - lib/git_pivotal_tracker/info.rb
83
94
  - lib/git_pivotal_tracker/story.rb
84
95
  - lib/git_pivotal_tracker/version.rb
85
- - spec/git_pivotal_tracker_spec.rb
96
+ - spec/fixtures/finish_story.xml
97
+ - spec/fixtures/no_stories.xml
98
+ - spec/fixtures/one_story.xml
99
+ - spec/fixtures/project.xml
100
+ - spec/fixtures/start_story.xml
101
+ - spec/fixtures/story.xml
102
+ - spec/git_pivotal_tracker/base_spec.rb
103
+ - spec/git_pivotal_tracker/finish_spec.rb
104
+ - spec/git_pivotal_tracker/story_spec.rb
86
105
  - spec/spec_helper.rb
87
106
  has_rdoc: true
88
107
  homepage: https://github.com/blindsey/git_pivotal_tracker
@@ -113,5 +132,13 @@ signing_key:
113
132
  specification_version: 3
114
133
  summary: A git workflow integrated with Pivotal Tracker
115
134
  test_files:
116
- - spec/git_pivotal_tracker_spec.rb
135
+ - spec/fixtures/finish_story.xml
136
+ - spec/fixtures/no_stories.xml
137
+ - spec/fixtures/one_story.xml
138
+ - spec/fixtures/project.xml
139
+ - spec/fixtures/start_story.xml
140
+ - spec/fixtures/story.xml
141
+ - spec/git_pivotal_tracker/base_spec.rb
142
+ - spec/git_pivotal_tracker/finish_spec.rb
143
+ - spec/git_pivotal_tracker/story_spec.rb
117
144
  - spec/spec_helper.rb
@@ -1,4 +0,0 @@
1
- require File.join(File.dirname(__FILE__), %w[spec_helper])
2
-
3
- describe GitPivotalTracker do
4
- end