pivotal_doc 1.4.0 → 1.4.1

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.
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