pivotal_doc 1.4.0 → 1.4.1

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 1.4.0
1
+ 1.4.1
data/lib/pivotal_doc.rb CHANGED
@@ -16,13 +16,10 @@ require File.join('pivotal_doc/exceptions')
16
16
  require File.join('pivotal_doc/generator')
17
17
 
18
18
  #Core classes
19
- require File.join('pivotal_doc/work')
20
- require File.join('pivotal_doc/release')
21
19
  require File.join('pivotal_doc/sprint')
22
20
 
23
21
  #Generators
24
22
  require File.join('pivotal_doc/generators', 'base')
25
23
  require File.join('pivotal_doc/generators', 'html')
26
24
  require File.join('pivotal_doc/generators', 'csv')
27
- require File.join('pivotal_doc/generators', 'sprint')
28
25
 
@@ -1,15 +1,13 @@
1
1
  module PivotalDoc
2
2
  class Generator
3
3
  class << self
4
- #TODO: Clean this mutatant up
5
4
  def generate(format, settings={})
6
5
  raise FormatNotSupported.new(format) unless generators.has_key?(format)
7
6
  config= PivotalDoc::Configuration.new(settings)
8
7
  config.authenticate!
9
- releases= collect_releases!(config)
10
- releases.each do |release|
11
- generator= release.generator(format) if release.respond_to?(:generator)
12
- (generator || generators[format]).new(release, config.settings).render_doc
8
+ sprints= collect_sprints!(config)
9
+ sprints.each do |sprint|
10
+ generators[format].new(sprint, config.settings).render_doc
13
11
  end
14
12
  true
15
13
  end
@@ -18,17 +16,13 @@ module PivotalDoc
18
16
  { :html=>Generators::HTML, :csv=>Generators::CSV }
19
17
  end
20
18
 
21
- def collect_releases!(config)
22
- releases= []
19
+ def collect_sprints!(config)
20
+ sprints= []
23
21
  config.projects.each do |name, _attrs|
24
22
  project= PT::Project.find(_attrs['id'].to_i)
25
- if _attrs['current']
26
- releases << Sprint.new(project)
27
- else
28
- releases << Release.new(project)
29
- end
23
+ sprints << PivotalDoc::Sprint.new(project, _attrs['current'])
30
24
  end
31
- return releases
25
+ return sprints
32
26
  end
33
27
  end
34
28
  end
@@ -1,8 +1,10 @@
1
1
  module PivotalDoc
2
2
  module Generators
3
3
  class Base
4
- def initialize(release, options={})
5
- @release= release
4
+ TEMPLATE_PATH= "#{PROJECT_ROOT}/templates"
5
+
6
+ def initialize(sprint, options={})
7
+ @sprint= sprint
6
8
  @options= options
7
9
  end
8
10
 
@@ -13,7 +15,7 @@ module PivotalDoc
13
15
  def output_file
14
16
  name= @options['output_file']
15
17
  unless name
16
- name=@release.name || @release.project_name || self.object_id.to_s
18
+ name=@sprint.release_name || @sprint.project_name || self.object_id.to_s
17
19
  name.gsub!(/\//, '') and name.gsub!(/\s/,'')
18
20
  end
19
21
  File.join(output_path, (name + output_ext))
@@ -40,7 +42,7 @@ module PivotalDoc
40
42
  end
41
43
 
42
44
  def template
43
- path= File.join(PROJECT_ROOT, 'templates', template_name)
45
+ path= File.join(TEMPLATE_PATH, template_name)
44
46
  raise TemplateNonExistent.new(template_name) unless File.exists?(path)
45
47
  @template ||= File.read(path)
46
48
  end
@@ -11,7 +11,7 @@ module PivotalDoc
11
11
  def render_doc
12
12
  output = FasterCSV.generate do |csv|
13
13
  csv << COLUMNS.clone
14
- @release.features.each {|f| csv << fields(f) }
14
+ @sprint.features.each {|f| csv << fields(f) }
15
15
  end
16
16
  super(output)
17
17
  end
@@ -6,7 +6,7 @@ module PivotalDoc
6
6
  end
7
7
  def output_ext; '.html' end
8
8
  def render_doc
9
- html= Haml::Engine.new(template).render(Object.new, {:release=>@release})
9
+ html= Haml::Engine.new(template).render(Object.new, {:sprint=>@sprint})
10
10
  super(html)
11
11
  end
12
12
  end
@@ -1,24 +1,67 @@
1
1
  module PivotalDoc
2
- class Sprint
3
- include Work
2
+ class Sprint
3
+ attr_reader :project, :iteration
4
+
5
+ def initialize(project, current=false)
6
+ @project= project
7
+ @current= current
8
+ @iteration= (@current) ? current_iteration : latest_iteration
9
+ end
10
+
11
+ def current?
12
+ @current
13
+ end
4
14
 
5
- attr_reader :project
6
- attr_reader :iteration
15
+ def project_name
16
+ @project.name
17
+ end
18
+
19
+ def features
20
+ self.stories + self.bugs + self.chores
21
+ end
22
+
23
+ def stories
24
+ @stories ||= filter_stories
25
+ end
7
26
 
8
- def initialize(project)
9
- @project= project
10
- @iteration= PT::Iteration.current(project)
27
+ def bugs
28
+ @bugs ||= filter_stories('bug')
29
+ end
30
+
31
+ def chores
32
+ @chores ||= filter_stories('chore')
33
+ end
34
+
35
+ def release
36
+ @release ||= self.iteration.stories.detect{|s| s.story_type.downcase=='release'} if self.iteration.stories
11
37
  end
12
-
13
- def name; nil end
14
38
 
15
- def generator(format=:html)
16
- {:html=>PivotalDoc::Generators::Sprint}[format]
39
+ def release_name
40
+ release.name if release.respond_to?(:name)
17
41
  end
18
42
 
43
+ def latest_iteration
44
+ PT::Iteration.done(@project, :offset=>'-1').first
45
+ end
46
+
47
+ def current_iteration
48
+ PT::Iteration.current(@project)
49
+ end
50
+
51
+ [:stories, :bugs, :chores].each do |m|
52
+ define_method("accepted_#{m}") do
53
+ self.send(m).reject{|s| s.current_state.downcase != 'accepted' }
54
+ end
55
+ define_method("#{m}_delivered") do
56
+ self.send("accepted_#{m}".to_sym).size
57
+ end
58
+ end
59
+
19
60
  private
20
61
  def filter_stories(type='feature')
21
- self.iteration.stories.reject {|s| s.story_type.downcase != type }
62
+ self.iteration.stories.reject do |s|
63
+ s.story_type.downcase != type
64
+ end
22
65
  end
23
66
  end
24
67
  end
@@ -1,23 +1,4 @@
1
1
  module PivotalDoc
2
2
  module Work
3
- def project_name
4
- @project.name
5
- end
6
-
7
- def features
8
- self.stories + self.bugs + self.chores
9
- end
10
-
11
- def stories
12
- @stories ||= filter_stories
13
- end
14
-
15
- def bugs
16
- @bugs ||= filter_stories('bug')
17
- end
18
-
19
- def chores
20
- @chores ||= filter_stories('chore')
21
- end
22
3
  end
23
4
  end
data/pivotal_doc.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{pivotal_doc}
8
- s.version = "1.4.0"
8
+ s.version = "1.4.1"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Tim Linquist"]
@@ -51,8 +51,6 @@ Gem::Specification.new do |s|
51
51
  "lib/pivotal_doc/generators/base.rb",
52
52
  "lib/pivotal_doc/generators/csv.rb",
53
53
  "lib/pivotal_doc/generators/html.rb",
54
- "lib/pivotal_doc/generators/sprint.rb",
55
- "lib/pivotal_doc/release.rb",
56
54
  "lib/pivotal_doc/sprint.rb",
57
55
  "lib/pivotal_doc/work.rb",
58
56
  "pivotal_doc.gemspec",
@@ -66,8 +64,6 @@ Gem::Specification.new do |s|
66
64
  "spec/lib/generators/base_spec.rb",
67
65
  "spec/lib/generators/csv_spec.rb",
68
66
  "spec/lib/generators/html_spec.rb",
69
- "spec/lib/generators/sprint_spec.rb",
70
- "spec/lib/release_spec.rb",
71
67
  "spec/lib/sprint_spec.rb",
72
68
  "spec/spec.opts",
73
69
  "spec/spec_helper.rb",
@@ -76,6 +72,7 @@ Gem::Specification.new do |s|
76
72
  "templates/fancy.haml",
77
73
  "templates/output.csv",
78
74
  "templates/output.haml",
75
+ "templates/release.haml",
79
76
  "templates/sprint.haml"
80
77
  ]
81
78
  s.homepage = %q{http://github.com/timo3377/pivotal_doc}
@@ -89,8 +86,6 @@ Gem::Specification.new do |s|
89
86
  "spec/lib/generators/base_spec.rb",
90
87
  "spec/lib/generators/csv_spec.rb",
91
88
  "spec/lib/generators/html_spec.rb",
92
- "spec/lib/generators/sprint_spec.rb",
93
- "spec/lib/release_spec.rb",
94
89
  "spec/lib/sprint_spec.rb",
95
90
  "spec/spec_helper.rb",
96
91
  "spec/support/mocks_helper.rb",
@@ -13,7 +13,7 @@ describe PivotalDoc::Generator do
13
13
 
14
14
  describe "Configuring" do
15
15
  before(:each) do
16
- PivotalDoc::Generator.stub!(:collect_releases!).and_return([])
16
+ PivotalDoc::Generator.stub!(:collect_sprints!).and_return([])
17
17
  end
18
18
  it "should create a config object from the settings" do
19
19
  settings= {}
@@ -28,48 +28,28 @@ describe PivotalDoc::Generator do
28
28
  end
29
29
  end
30
30
 
31
- describe "releases" do
31
+ describe "sprints" do
32
32
  before(:each) do
33
- @release= mocks_helper(:release)
34
- PivotalDoc::Release.stub!(:new).and_return(@release)
33
+ @sprint= mocks_helper(:sprint)
34
+ PivotalDoc::Sprint.stub!(:new).and_return(@sprint)
35
35
  end
36
36
 
37
- it "should create a release for each project" do
37
+ it "should create a sprint for each project" do
38
38
  PT::Iteration.stub!(:current).and_return(mocks_helper(:iteration))
39
39
  @config.projects.each do |name, settings|
40
- PT::Project.should_receive(:find).with(settings['id'].to_i).and_return(@release.project)
41
- end
42
- releases= PivotalDoc::Generator.collect_releases!(@config)
43
- releases.size.should eql(@config.projects.size)
44
- end
45
-
46
- describe "current" do
47
- it "create a current iteration for the release if current is set for the project" do
48
- PT::Project.stub!(:find).and_return(@release.project)
49
- iteration= mocks_helper(:iteration)
50
- PT::Iteration.should_receive(:current).exactly(:once).and_return(iteration)
51
- PivotalDoc::Generator.collect_releases!(@config)
52
- end
53
-
54
- it "create a sprint for the current iteration instead of a release" do
55
- PT::Project.stub!(:find).and_return(@release.project)
56
- iteration= mocks_helper(:iteration)
57
- PT::Iteration.stub!(:current).and_return(iteration)
58
- releases= PivotalDoc::Generator.collect_releases!(@config)
59
- releases.last.should be_an_instance_of(PivotalDoc::Sprint)
40
+ PT::Project.should_receive(:find).with(settings['id'].to_i).and_return(@sprint.project)
60
41
  end
42
+ sprints= PivotalDoc::Generator.collect_sprints!(@config)
43
+ sprints.size.should eql(@config.projects.size)
61
44
  end
62
45
  end
63
46
 
64
47
  describe "generation" do
65
48
  before(:each) do
66
49
  @config.stub!(:authenticate!).and_return(true)
67
- @release = mocks_helper(:release)
68
- PT::Iteration.stub!(:current).and_return(mocks_helper(:iteration))
69
- @sprint = PivotalDoc::Sprint.new(@release.project)
70
- PT::Project.stub!(:find).and_return(@release.project)
50
+ @sprint = mocks_helper(:sprint)
51
+ PT::Project.stub!(:find).and_return(@sprint.project)
71
52
  PivotalDoc::Sprint.stub!(:new).and_return(@sprint)
72
- PivotalDoc::Release.stub!(:new).and_return(@release)
73
53
  end
74
54
 
75
55
  describe "Formattting" do
@@ -78,15 +58,9 @@ describe PivotalDoc::Generator do
78
58
  @html_gen= PivotalDoc::Generators::HTML.new({})
79
59
  @html_gen.stub!(:render_doc)
80
60
  end
81
- it "use the generators format if there is one" do
82
- sprint_generator= mock('PivotalDoc::Generators::Sprint')
83
- @sprint.generator(:html).should_receive(:new).exactly(:once).with(@sprint, @config.settings).and_return(sprint_generator)
84
- sprint_generator.should_receive(:render_doc)
85
- PivotalDoc::Generator.generate(:html)
86
- end
61
+
87
62
  it "should render the release with the specified format and custom settings" do
88
- @sprint.generator(:html).stub!(:new).and_return(@html_gen)
89
- PivotalDoc::Generators::HTML.should_receive(:new).with(@release, @config.settings).and_return(@html_gen)
63
+ PivotalDoc::Generators::HTML.should_receive(:new).with(@sprint, @config.settings).and_return(@html_gen)
90
64
  PivotalDoc::Generator.generate(:html)
91
65
  end
92
66
  it "should raise an error if the specified format isn't supported" do
@@ -2,8 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe PivotalDoc::Generators::Base do
4
4
  before(:each) do
5
- @release= mocks_helper(:release)
6
- @base= PivotalDoc::Generators::Base.new(@release)
5
+ @sprint= mocks_helper(:sprint)
6
+ @base= PivotalDoc::Generators::Base.new(@sprint)
7
7
  end
8
8
  it "should raise an exception if the template doesn't exist" do
9
9
  @base.stub!(:template_name).and_return('non-existent.txt')
@@ -21,24 +21,24 @@ describe PivotalDoc::Generators::Base do
21
21
 
22
22
  describe "options" do
23
23
  it "should be a fully qualified file" do
24
- base= PivotalDoc::Generators::Base.new(@release, {:output_file=>'my_file'})
24
+ base= PivotalDoc::Generators::Base.new(@sprint, {:output_file=>'my_file'})
25
25
  f= File.open(base.output_file, 'w')
26
26
  f.should be_an_instance_of(File)
27
27
  File.delete(f.path)
28
28
  end
29
29
 
30
30
  it "should use the output_file if present" do
31
- base= PivotalDoc::Generators::Base.new(@release, {'output_file'=>'my_file'})
31
+ base= PivotalDoc::Generators::Base.new(@sprint, {'output_file'=>'my_file'})
32
32
  base.output_file.should =~ /\/my_file/
33
33
  end
34
34
 
35
35
  it "should default the output_file to the release's name (unique filename for multiple projects)" do
36
- base= PivotalDoc::Generators::Base.new(@release)
37
- base.output_file.should =~ /\/#{@release.name}/
36
+ base= PivotalDoc::Generators::Base.new(@sprint)
37
+ base.output_file.should =~ /\/#{@sprint.release_name}/
38
38
  end
39
39
 
40
40
  it "should use the output_path if present" do
41
- base= PivotalDoc::Generators::Base.new(@release, {'output_path'=>'my_path'})
41
+ base= PivotalDoc::Generators::Base.new(@sprint, {'output_path'=>'my_path'})
42
42
  base.output_path.should =~ /^my_path/
43
43
  end
44
44
 
@@ -2,8 +2,8 @@ require File.dirname(__FILE__) + '/../../spec_helper'
2
2
 
3
3
  describe PivotalDoc::Generators::CSV do
4
4
  before(:each) do
5
- @release= mocks_helper(:release)
6
- @csv= PivotalDoc::Generators::CSV.new(@release)
5
+ @sprint= mocks_helper(:sprint)
6
+ @csv= PivotalDoc::Generators::CSV.new(@sprint)
7
7
  end
8
8
 
9
9
  after(:each) do
@@ -15,7 +15,7 @@ describe PivotalDoc::Generators::CSV do
15
15
  @csv.render_doc
16
16
  output= File.read(@csv.output_file)
17
17
  output.should =~ /#{PivotalDoc::Generators::CSV::COLUMNS.join(',')}/
18
- @release.features.each{|f| output =~ @csv.fields(f) }
18
+ @sprint.features.each{|f| output =~ @csv.fields(f) }
19
19
  end
20
20
 
21
21
  it "should read the file contents" do
@@ -27,7 +27,7 @@ describe PivotalDoc::Generators::CSV do
27
27
  end
28
28
 
29
29
  it "include each field" do
30
- fields= @csv.fields(@release.features.first)
30
+ fields= @csv.fields(@sprint.features.first)
31
31
  fields.should be_an_instance_of(Array)
32
32
  fields.should have(PivotalDoc::Generators::CSV::COLUMNS.size).items
33
33
  end
@@ -2,8 +2,8 @@ require 'spec_helper'
2
2
 
3
3
  describe PivotalDoc::Generators::HTML do
4
4
  before(:each) do
5
- @release= mocks_helper(:release)
6
- @html= PivotalDoc::Generators::HTML.new(@release)
5
+ @sprint= mocks_helper(:sprint)
6
+ @html= PivotalDoc::Generators::HTML.new(@sprint)
7
7
  @engine= Haml::Engine.new('')
8
8
  end
9
9
 
@@ -24,7 +24,7 @@ describe PivotalDoc::Generators::HTML do
24
24
 
25
25
  it "should use the template_name if specified" do
26
26
  options= {'template_name'=>'fancy.html'}
27
- html= PivotalDoc::Generators::HTML.new(@release, options)
27
+ html= PivotalDoc::Generators::HTML.new(@sprint, options)
28
28
  html.template_name.should eql(options['template_name'])
29
29
  end
30
30
 
@@ -3,42 +3,89 @@ require 'spec_helper'
3
3
  describe PivotalDoc::Sprint do
4
4
  before(:each) do
5
5
  @project= PT::Project.new
6
- @iteration= PT::Iteration.new
7
- PT::Iteration.stub!(:current).and_return([@iteration])
6
+ @latest_iteration, @current_iteration = PT::Iteration.new, PT::Iteration.new
7
+ PT::Iteration.stub!(:done).and_return([@latest_iteration])
8
8
  @sprint= PivotalDoc::Sprint.new(@project)
9
9
  end
10
10
 
11
- it "not have a release name" do
12
- @sprint.name.should be_nil
11
+ it "should get the last 'done' iteration for the project" do
12
+ PT::Iteration.should_receive(:done).with(@project, :offset=>'-1').and_return([@latest_iteration])
13
+ @sprint.latest_iteration.should eql(@latest_iteration)
13
14
  end
14
15
 
15
- it "know the html generator" do
16
- @sprint.generator(:html).should eql(PivotalDoc::Generators::Sprint)
16
+ it "should get the current iteration for the project" do
17
+ PT::Iteration.should_receive(:current).and_return(@current_iteration)
18
+ @sprint.current_iteration.should eql(@current_iteration)
17
19
  end
18
-
19
- it "only know the html generator" do
20
- @sprint.generator(:unknown).should be_nil
21
- end
22
-
23
- describe "stories" do
20
+
21
+ describe "an iteration" do
24
22
  before(:each) do
25
- @stories= PTApiHelpers::mock_stories
26
- @sprint.iteration.stub!(:stories).and_return(@stories)
23
+ @sprint.stub!(:latest_iteration).and_return(@latest_iteration)
27
24
  end
28
-
29
- it "should get the stories only" do
30
- @sprint.iteration.should_receive(:stories).and_return(@stories)
31
- @sprint.stories.each{|s| s.story_type.downcase.should eql('feature') }
25
+
26
+ it "should default the iteration to the latest_iteration (last 'done') if current isn't set" do
27
+ PT::Iteration.should_receive(:done).and_return([@latest_iteration])
28
+ sprint= PivotalDoc::Sprint.new(@project)
29
+ sprint.iteration.should eql(@latest_iteration)
32
30
  end
33
-
34
- it "should get the bugs only" do
35
- @sprint.iteration.should_receive(:stories).and_return(@stories)
36
- @sprint.bugs.each{|b| b.story_type.downcase.should eql('bug') }
31
+
32
+ describe "release of sprint" do
33
+ before(:each) do
34
+ @stories= PTApiHelpers::mock_stories
35
+ @release= PTApiHelpers::mock_actual_release
36
+ @latest_iteration.stub!(:stories).and_return(@stories)
37
+ end
38
+
39
+ it "should find the \"release\" if there is one" do
40
+ @latest_iteration.should_receive(:stories).and_return(@stories)
41
+ @sprint.release.story_type.should eql('release')
42
+ end
43
+
44
+ it "should know the name of the release" do
45
+ @sprint.release_name.should eql(@release.name)
46
+ end
37
47
  end
38
48
 
39
- it "should get the chores only" do
40
- @sprint.iteration.should_receive(:stories).and_return(@stories)
41
- @sprint.chores.each{|c| c.story_type.downcase.should eql('chore') }
49
+ describe "stories" do
50
+ before(:each) do
51
+ @stories= PTApiHelpers::mock_stories
52
+ @latest_iteration.stub!(:stories).and_return(@stories)
53
+ end
54
+
55
+ it "should get the stories only" do
56
+ @latest_iteration.should_receive(:stories).and_return(@stories)
57
+ @sprint.stories.each{|s| s.story_type.downcase.should eql('feature') }
58
+ end
59
+
60
+ it "should get the bugs only" do
61
+ @latest_iteration.should_receive(:stories).and_return(@stories)
62
+ @sprint.bugs.each{|b| b.story_type.downcase.should eql('bug') }
63
+ end
64
+
65
+ it "should get the chores only" do
66
+ @latest_iteration.should_receive(:stories).and_return(@stories)
67
+ @sprint.chores.each{|c| c.story_type.downcase.should eql('chore') }
68
+ end
69
+
70
+ describe "finished work" do
71
+ [:stories, :chores, :bugs].each do |m|
72
+ it "should know the #{m} delivered in this release" do
73
+ @sprint.send("#{m}_delivered").should eql(@sprint.send("accepted_#{m}").size)
74
+ end
75
+ end
76
+
77
+ it "should only get the \"delivered\" stories" do
78
+ @sprint.accepted_stories.each{|s| s.current_state.downcase.should eql('accepted')}
79
+ end
80
+
81
+ it "should only get the \"delivered\" bugs" do
82
+ @sprint.accepted_bugs.each{|b| b.current_state.downcase.should eql('accepted')}
83
+ end
84
+
85
+ it "should only get the \"accepted\" chores" do
86
+ @sprint.accepted_chores.each{|c| c.current_state.downcase.should eql('accepted')}
87
+ end
88
+ end
42
89
  end
43
- end
90
+ end
44
91
  end
@@ -5,12 +5,13 @@ module MocksHelper
5
5
  end
6
6
 
7
7
  private
8
- def release
9
- release= PivotalDoc::Release.new(project, iteration)
10
- release.stub!(:stories).and_return(PTApiHelpers::mock_stories)
11
- release.stub!(:bugs).and_return(PTApiHelpers::mock_bugs)
12
- release.stub!(:chores).and_return(PTApiHelpers::mock_chores)
13
- release
8
+ def sprint
9
+ PT::Iteration.stub!(:current).and_return(iteration)
10
+ sprint= PivotalDoc::Sprint.new(project, iteration)
11
+ sprint.stub!(:stories).and_return(PTApiHelpers::mock_stories)
12
+ sprint.stub!(:bugs).and_return(PTApiHelpers::mock_bugs)
13
+ sprint.stub!(:chores).and_return(PTApiHelpers::mock_chores)
14
+ sprint
14
15
  end
15
16
 
16
17
  def project
@@ -23,7 +24,7 @@ module MocksHelper
23
24
 
24
25
  def mocks
25
26
  @@mocks= {
26
- :release=>release,
27
+ :sprint=>sprint,
27
28
  :project=>project,
28
29
  :iteration=>iteration
29
30
  }
@@ -2,7 +2,7 @@
2
2
  %html
3
3
  %head
4
4
  %meta{'http-equiv' => 'Content-Type', :content => 'text/html;charset=utf-8'}
5
- %title= release.name
5
+ %title= sprint.release_name
6
6
  %style{:type => "text/css", :media => "screen"}
7
7
  :plain
8
8
  p,div,h1,h2,h3,h4,h5,h6,span,a {font-family: Arial}
@@ -19,35 +19,11 @@
19
19
  div.item {padding-left: .4em}
20
20
  div.item_info {padding-left: .4em}
21
21
  %body
22
- #release_doc
23
- #release_info
24
- %h2= "Announcing the \"#{release.name}\" release for the #{release.project_name} project"
25
- %p
26
- = "This sprint began on #{release.iteration.start.fancy_format} and was completed on #{release.iteration.finish.fancy_format}. It includes #{release.stories_delivered} new stories, #{release.bugs_delivered} bug fixes, and #{release.chores_delivered} miscellaneous chores."
27
- #stories
28
- %h3 Accepted Stories
29
- - release.stories.each do |story|
30
- .item
31
- %h4= "Story ##{story.id} - #{story.name}"
32
- .item_info
33
- %p= "Requestor: #{story.requested_by}"
34
- %p= "Completed By: #{story.owned_by}"
35
- %p= "Description: #{story.description}"
36
- #bugs
37
- %h3 Bug Fixes
38
- - release.bugs.each do |bug|
39
- .item
40
- %h4= "Bug ##{bug.id} - #{bug.name}"
41
- .item_info
42
- %p= "Requestor: #{bug.requested_by}"
43
- %p= "Completed By: #{bug.owned_by}"
44
- %p= "Description: #{bug.description}"
45
- #chores
46
- %h3 Miscellaneous Chores
47
- - release.chores.each do |chore|
48
- .item
49
- %h4= "Chore ##{chore.id} - #{chore.name}"
50
- .item_info
51
- %p= "Requestor: #{chore.requested_by}"
52
- %p= "Completed By: #{chore.owned_by}"
53
- %p= "Description: #{chore.description}"
22
+ #doc
23
+ #info
24
+ - path= PivotalDoc::Generators::Base::TEMPLATE_PATH
25
+ - if sprint.current?
26
+ %p= Haml::Engine.new(File.read(path + '/sprint.haml')).render(Object.new, {:sprint=>sprint})
27
+ - else
28
+ %p= Haml::Engine.new(File.read(path + '/release.haml')).render(Object.new, {:sprint=>sprint})
29
+
@@ -0,0 +1,30 @@
1
+ %h2= "Announcing the \"#{sprint.release_name}\" release for the #{sprint.project_name} project"
2
+ %p
3
+ = "This sprint began on #{sprint.iteration.start.fancy_format} and was completed on #{sprint.iteration.finish.fancy_format}. It includes #{sprint.stories_delivered} new stories, #{sprint.bugs_delivered} bug fixes, and #{sprint.chores_delivered} miscellaneous chores."
4
+ #stories
5
+ %h3 Accepted Stories
6
+ - sprint.accepted_stories.each do |story|
7
+ .item
8
+ %h4= "Story ##{story.id} - #{story.name}"
9
+ .item_info
10
+ %p= "Requestor: #{story.requested_by}"
11
+ %p= "Completed By: #{story.owned_by}"
12
+ %p= "Description: #{story.description}"
13
+ #bugs
14
+ %h3 Bug Fixes
15
+ - sprint.accepted_bugs.each do |bug|
16
+ .item
17
+ %h4= "Bug ##{bug.id} - #{bug.name}"
18
+ .item_info
19
+ %p= "Requestor: #{bug.requested_by}"
20
+ %p= "Completed By: #{bug.owned_by}"
21
+ %p= "Description: #{bug.description}"
22
+ #chores
23
+ %h3 Miscellaneous Chores
24
+ - sprint.accepted_chores.each do |chore|
25
+ .item
26
+ %h4= "Chore ##{chore.id} - #{chore.name}"
27
+ .item_info
28
+ %p= "Requestor: #{chore.requested_by}"
29
+ %p= "Completed By: #{chore.owned_by}"
30
+ %p= "Description: #{chore.description}"
@@ -1,48 +1,25 @@
1
- !!! Strict
2
- %html
3
- %head
4
- %meta{'http-equiv' => 'Content-Type', :content => 'text/html;charset=utf-8'}
5
- %title= sprint.iteration.start.fancy_format
6
- %style{:type => "text/css", :media => "screen"}
7
- :plain
8
- p,div,h1,h2,h3,h4,h5,h6,span,a {font-family: Arial}
9
- div#sprint_doc {padding-left: .5em;}
10
- h2, h3 {padding: .5em 0;}
11
- h3 {text-decoration: underline;}
12
- div#sprint_doc {
13
- width: 80%;
14
- margin-left: auto;
15
- margin-right: auto;
16
- text-align: left;
17
- }
18
- div#chores, div#bugs, div#stories{ padding-left: 0.6em }
19
- div.item {padding-left: .4em}
20
- div.item_info {padding-left: .4em}
21
- %body
22
- #sprint_doc
23
- #sprint_info
24
- %h2= "This sprint begins on #{sprint.iteration.start.fancy_format} and ends on #{sprint.iteration.finish.fancy_format}."
25
- #stories
26
- %h3 Proposed Stories
27
- - sprint.stories.each do |story|
28
- .item
29
- %h4= "Story ##{story.id} - #{story.name}"
30
- .item_info
31
- %p= "Requestor: #{story.requested_by}"
32
- %p= "Description: #{story.description}"
33
- #bugs
34
- %h3 Bug Fixes
35
- - sprint.bugs.each do |bug|
36
- .item
37
- %h4= "Bug ##{bug.id} - #{bug.name}"
38
- .item_info
39
- %p= "Requestor: #{bug.requested_by}"
40
- %p= "Description: #{bug.description}"
41
- #chores
42
- %h3 Miscellaneous Chores
43
- - sprint.chores.each do |chore|
44
- .item
45
- %h4= "Chore ##{chore.id} - #{chore.name}"
46
- .item_info
47
- %p= "Requestor: #{chore.requested_by}"
48
- %p= "Description: #{chore.description}"
1
+ %h2= "This sprint begins on #{sprint.iteration.start.fancy_format} and ends on #{sprint.iteration.finish.fancy_format}."
2
+ #stories
3
+ %h3 Proposed Stories
4
+ - sprint.stories.each do |story|
5
+ .item
6
+ %h4= "Story ##{story.id} - #{story.name}"
7
+ .item_info
8
+ %p= "Requestor: #{story.requested_by}"
9
+ %p= "Description: #{story.description}"
10
+ #bugs
11
+ %h3 Bug Fixes
12
+ - sprint.bugs.each do |bug|
13
+ .item
14
+ %h4= "Bug ##{bug.id} - #{bug.name}"
15
+ .item_info
16
+ %p= "Requestor: #{bug.requested_by}"
17
+ %p= "Description: #{bug.description}"
18
+ #chores
19
+ %h3 Miscellaneous Chores
20
+ - sprint.chores.each do |chore|
21
+ .item
22
+ %h4= "Chore ##{chore.id} - #{chore.name}"
23
+ .item_info
24
+ %p= "Requestor: #{chore.requested_by}"
25
+ %p= "Description: #{chore.description}"
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pivotal_doc
3
3
  version: !ruby/object:Gem::Version
4
- hash: 7
4
+ hash: 5
5
5
  prerelease:
6
6
  segments:
7
7
  - 1
8
8
  - 4
9
- - 0
10
- version: 1.4.0
9
+ - 1
10
+ version: 1.4.1
11
11
  platform: ruby
12
12
  authors:
13
13
  - Tim Linquist
@@ -218,8 +218,6 @@ files:
218
218
  - lib/pivotal_doc/generators/base.rb
219
219
  - lib/pivotal_doc/generators/csv.rb
220
220
  - lib/pivotal_doc/generators/html.rb
221
- - lib/pivotal_doc/generators/sprint.rb
222
- - lib/pivotal_doc/release.rb
223
221
  - lib/pivotal_doc/sprint.rb
224
222
  - lib/pivotal_doc/work.rb
225
223
  - pivotal_doc.gemspec
@@ -233,8 +231,6 @@ files:
233
231
  - spec/lib/generators/base_spec.rb
234
232
  - spec/lib/generators/csv_spec.rb
235
233
  - spec/lib/generators/html_spec.rb
236
- - spec/lib/generators/sprint_spec.rb
237
- - spec/lib/release_spec.rb
238
234
  - spec/lib/sprint_spec.rb
239
235
  - spec/spec.opts
240
236
  - spec/spec_helper.rb
@@ -243,6 +239,7 @@ files:
243
239
  - templates/fancy.haml
244
240
  - templates/output.csv
245
241
  - templates/output.haml
242
+ - templates/release.haml
246
243
  - templates/sprint.haml
247
244
  has_rdoc: true
248
245
  homepage: http://github.com/timo3377/pivotal_doc
@@ -285,8 +282,6 @@ test_files:
285
282
  - spec/lib/generators/base_spec.rb
286
283
  - spec/lib/generators/csv_spec.rb
287
284
  - spec/lib/generators/html_spec.rb
288
- - spec/lib/generators/sprint_spec.rb
289
- - spec/lib/release_spec.rb
290
285
  - spec/lib/sprint_spec.rb
291
286
  - spec/spec_helper.rb
292
287
  - spec/support/mocks_helper.rb
@@ -1,18 +0,0 @@
1
- module PivotalDoc
2
- module Generators
3
- class Sprint < Base
4
- def initialize(sprint, options={})
5
- @sprint=sprint
6
- super(@sprint, options)
7
- end
8
- def template_name
9
- @options['template_name'] || 'sprint.haml'
10
- end
11
- def output_ext; '.html' end
12
- def render_doc
13
- html= Haml::Engine.new(template).render(Object.new, {:sprint=>@sprint})
14
- super(html)
15
- end
16
- end
17
- end
18
- end
@@ -1,36 +0,0 @@
1
- module PivotalDoc
2
- class Release
3
- include Work
4
-
5
- attr_reader :project
6
- attr_reader :iteration
7
-
8
- def initialize(project, iteration=nil)
9
- @project= project
10
- @iteration= (iteration || latest_iteration)
11
- end
12
-
13
- def me
14
- @me ||= self.iteration.stories.detect{|s| s.story_type.downcase=='release'} if self.iteration.stories
15
- end
16
-
17
- def name
18
- me.name if me.respond_to?(:name)
19
- end
20
-
21
- def latest_iteration
22
- PT::Iteration.done(@project, :offset=>'-1').first
23
- end
24
-
25
- [:stories, :bugs, :chores].each do |m|
26
- define_method("#{m}_delivered") { self.send(m).size }
27
- end
28
-
29
- private
30
- def filter_stories(type='feature')
31
- self.iteration.stories.reject do |s|
32
- s.story_type.downcase != type || s.current_state.downcase != 'accepted'
33
- end
34
- end
35
- end
36
- end
@@ -1,40 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe PivotalDoc::Generators::Sprint do
4
- before(:each) do
5
- @release= mocks_helper(:release)
6
- @sprint= PivotalDoc::Generators::Sprint.new(@release)
7
- @engine= Haml::Engine.new('')
8
- end
9
-
10
- after(:each) do
11
- File.delete(@sprint.output_file) if File.exists?(@sprint.output_file)
12
- end
13
-
14
- it "should open the output file and write the compiled haml (html)" do
15
- Haml::Engine.stub!(:new).and_return(@engine)
16
- @engine.stub!(:render).and_return('compiled haml')
17
- @sprint.render_doc
18
- File.read(@sprint.output_file).should eql('compiled haml')
19
- end
20
-
21
- it "should read the file contents" do
22
- @sprint.template.should be_an_instance_of(String)
23
- end
24
-
25
- it "should use the template_name if specified" do
26
- options= {'template_name'=>'fancy.sprint.html'}
27
- html= PivotalDoc::Generators::HTML.new(@release, options)
28
- html.template_name.should eql(options['template_name'])
29
- end
30
-
31
- it "should know its template name" do
32
- @sprint.template_name.should =~ /\.haml$/
33
- end
34
-
35
- it "should render the release doc" do
36
- Haml::Engine.should_receive(:new).with(@sprint.template).and_return(@engine)
37
- @engine.should_receive(:render)
38
- @sprint.render_doc
39
- end
40
- end
@@ -1,92 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe PivotalDoc::Release do
4
- before(:each) do
5
- @project= PT::Project.new
6
- @latest_iteration= PT::Iteration.new
7
- PT::Iteration.stub!(:done).and_return([@latest_iteration])
8
- @release= PivotalDoc::Release.new(@project)
9
- end
10
-
11
- it "should get the last 'done' iteration for the project" do
12
- PT::Iteration.should_receive(:done).with(@project, :offset=>'-1')
13
- @release.latest_iteration
14
- end
15
-
16
- describe "the latest iteration" do
17
- before(:each) do
18
- @release.stub!(:latest_iteration).and_return(@latest_iteration)
19
- end
20
-
21
- it "should use the iteration if specified" do
22
- backlog= PTApiHelpers::mock_object('iterations')
23
- release= PivotalDoc::Release.new(@project, backlog)
24
- release.iteration.should eql(backlog)
25
- end
26
-
27
- it "should default the iteration to the latest_iteration (last 'done') if one isn't specified" do
28
- PT::Iteration.should_receive(:done).and_return([@latest_iteration])
29
- release= PivotalDoc::Release.new(@project)
30
- release.iteration.should eql(@latest_iteration)
31
- end
32
-
33
- describe "release of (me)" do
34
- before(:each) do
35
- @stories= PTApiHelpers::mock_stories
36
- @me= PTApiHelpers::mock_actual_release
37
- @latest_iteration.stub!(:stories).and_return(@stories)
38
- end
39
-
40
- it "should find the \"release\" if there is one" do
41
- @latest_iteration.should_receive(:stories).and_return(@stories)
42
- @release.me.story_type.should eql('release')
43
- end
44
-
45
- it "should know the name of the release" do
46
- @release.name.should eql(@me.name)
47
- end
48
- end
49
-
50
- describe "stories" do
51
- before(:each) do
52
- @stories= PTApiHelpers::mock_stories
53
- @latest_iteration.stub!(:stories).and_return(@stories)
54
- end
55
-
56
- it "should get the stories only" do
57
- @latest_iteration.should_receive(:stories).and_return(@stories)
58
- @release.stories.each{|s| s.story_type.downcase.should eql('feature') }
59
- end
60
-
61
- it "should get the bugs only" do
62
- @latest_iteration.should_receive(:stories).and_return(@stories)
63
- @release.bugs.each{|b| b.story_type.downcase.should eql('bug') }
64
- end
65
-
66
- it "should get the chores only" do
67
- @latest_iteration.should_receive(:stories).and_return(@stories)
68
- @release.chores.each{|c| c.story_type.downcase.should eql('chore') }
69
- end
70
-
71
- describe "finished work" do
72
- [:stories, :chores, :bugs].each do |m|
73
- it "should know the #{m} delivered in this release" do
74
- @release.send("#{m}_delivered").should eql(@release.send(m).size)
75
- end
76
- end
77
-
78
- it "should only get the \"delivered\" stories" do
79
- @release.stories.each{|s| s.current_state.downcase.should eql('accepted')}
80
- end
81
-
82
- it "should only get the \"delivered\" bugs" do
83
- @release.bugs.each{|b| b.current_state.downcase.should eql('accepted')}
84
- end
85
-
86
- it "should only get the \"accepted\" chores" do
87
- @release.chores.each{|c| c.current_state.downcase.should eql('accepted')}
88
- end
89
- end
90
- end
91
- end
92
- end