pivotal_doc 1.1.0
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/.gitignore +5 -0
- data/README +37 -0
- data/Rakefile +49 -0
- data/VERSION +1 -0
- data/assets/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png +0 -0
- data/assets/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png +0 -0
- data/assets/css/ui-lightness/images/ui-icons_222222_256x240.png +0 -0
- data/assets/css/ui-lightness/images/ui-icons_228ef1_256x240.png +0 -0
- data/assets/css/ui-lightness/images/ui-icons_ef8c08_256x240.png +0 -0
- data/assets/css/ui-lightness/images/ui-icons_ffd27a_256x240.png +0 -0
- data/assets/css/ui-lightness/images/ui-icons_ffffff_256x240.png +0 -0
- data/assets/css/ui-lightness/jquery-ui-1.8.5.custom.css +572 -0
- data/assets/js/jquery-1.4.2.min.js +154 -0
- data/assets/js/jquery-ui-1.8.5.custom.min.js +778 -0
- data/ext/date.rb +9 -0
- data/lib/pivotal_doc/configuration.rb +37 -0
- data/lib/pivotal_doc/exceptions.rb +22 -0
- data/lib/pivotal_doc/generator.rb +30 -0
- data/lib/pivotal_doc/generators/base.rb +52 -0
- data/lib/pivotal_doc/generators/html.rb +14 -0
- data/lib/pivotal_doc/generators/text.rb +12 -0
- data/lib/pivotal_doc/release.rb +50 -0
- data/lib/pivotal_doc.rb +14 -0
- data/pivotal_doc.gemspec +106 -0
- data/spec/fixtures/configs.yml +11 -0
- data/spec/fixtures/iterations.yml +4 -0
- data/spec/fixtures/projects.yml +11 -0
- data/spec/fixtures/stories.yml +87 -0
- data/spec/lib/configuration_spec.rb +88 -0
- data/spec/lib/generator_spec.rb +57 -0
- data/spec/lib/generators/base_spec.rb +64 -0
- data/spec/lib/generators/html_spec.rb +40 -0
- data/spec/lib/generators/text_spec.rb +25 -0
- data/spec/lib/release_spec.rb +92 -0
- data/spec/spec_helper.rb +9 -0
- data/spec/support/mocks_helper.rb +31 -0
- data/spec/support/pt_api_helpers.rb +42 -0
- data/templates/fancy.haml +74 -0
- data/templates/html_gen.haml +53 -0
- data/templates/text_gen.txt +0 -0
- metadata +164 -0
data/ext/date.rb
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
module PivotalDoc
|
2
|
+
class Configuration
|
3
|
+
attr_accessor :settings
|
4
|
+
attr_reader :authenticated
|
5
|
+
alias :authenticated? :authenticated
|
6
|
+
|
7
|
+
def initialize(settings)
|
8
|
+
@settings= settings.respond_to?(:merge) ? settings : YAML::load(File.new(settings))
|
9
|
+
end
|
10
|
+
|
11
|
+
def projects
|
12
|
+
self.settings['projects']
|
13
|
+
end
|
14
|
+
|
15
|
+
def output_path
|
16
|
+
self.settings['output_path']
|
17
|
+
end
|
18
|
+
|
19
|
+
def authenticate!
|
20
|
+
return if @authenticated
|
21
|
+
connection.token ? PT::Client.token=connection.token : PT::Client.token(connection.username, connection.password)
|
22
|
+
@authenticated= true
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
def connection
|
27
|
+
return @connection if @connection
|
28
|
+
@connection= Connection.new
|
29
|
+
@connection.token= settings['token']
|
30
|
+
@connection.username= settings['username']
|
31
|
+
@connection.password= settings['password']
|
32
|
+
@connection
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class Connection < Struct.new(:token, :username, :password); end
|
37
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
module PivotalDoc
|
2
|
+
class PivotalDocException < Exception
|
3
|
+
end
|
4
|
+
class FormatNotSupported < PivotalDocException
|
5
|
+
def initialize(format)
|
6
|
+
@format= format
|
7
|
+
end
|
8
|
+
|
9
|
+
def message
|
10
|
+
"The format (#{@format}) is not currently supported"
|
11
|
+
end
|
12
|
+
end
|
13
|
+
class TemplateNonExistent < PivotalDocException
|
14
|
+
def initialize(template_name)
|
15
|
+
@template_name= template_name
|
16
|
+
end
|
17
|
+
|
18
|
+
def message
|
19
|
+
"The template named \"#{@template_name}\" doesn't exist?"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module PivotalDoc
|
2
|
+
class Generator
|
3
|
+
class << self
|
4
|
+
attr_accessor :releases
|
5
|
+
attr_reader :config
|
6
|
+
|
7
|
+
def generate(format, settings={})
|
8
|
+
@config= PivotalDoc::Configuration.new(settings)
|
9
|
+
@config.authenticate!
|
10
|
+
raise FormatNotSupported.new(format) unless generators.has_key?(format)
|
11
|
+
collect_releases!
|
12
|
+
releases.each do |release|
|
13
|
+
generators[format].new(release, config.settings).render_doc
|
14
|
+
end
|
15
|
+
true
|
16
|
+
end
|
17
|
+
|
18
|
+
def generators
|
19
|
+
{ :text=>Generators::Text, :html=>Generators::HTML }
|
20
|
+
end
|
21
|
+
|
22
|
+
def collect_releases!
|
23
|
+
@releases= []
|
24
|
+
self.config.projects.each do |name, _attrs|
|
25
|
+
@releases << Release.new(PT::Project.find(_attrs['id'].to_i))
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
module PivotalDoc
|
2
|
+
module Generators
|
3
|
+
class Base
|
4
|
+
def initialize(release, options={})
|
5
|
+
@release= release
|
6
|
+
@options= options
|
7
|
+
end
|
8
|
+
|
9
|
+
def output_path
|
10
|
+
@options['output_path'] || absolute_path
|
11
|
+
end
|
12
|
+
|
13
|
+
def output_file
|
14
|
+
name= @options['output_file']
|
15
|
+
unless name
|
16
|
+
name=@release.name || self.object_id.to_s
|
17
|
+
name.gsub!(/\//, '') and name.gsub!(/\s/,'')
|
18
|
+
end
|
19
|
+
File.join(output_path, (name + output_ext))
|
20
|
+
end
|
21
|
+
|
22
|
+
def output_ext; '.default' end
|
23
|
+
|
24
|
+
def absolute_path
|
25
|
+
File.dirname(__FILE__)
|
26
|
+
end
|
27
|
+
|
28
|
+
def render_doc(output='')
|
29
|
+
begin
|
30
|
+
FileUtils.mkdir_p(output_path)
|
31
|
+
f= File.open(self.output_file, 'w+')
|
32
|
+
f.write(output)
|
33
|
+
rescue Exception=>e
|
34
|
+
$stdout.print(e.message)
|
35
|
+
$stdout.flush
|
36
|
+
ensure
|
37
|
+
f.close if f
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def template
|
42
|
+
path= File.join(PROJECT_ROOT, 'templates', template_name)
|
43
|
+
raise TemplateNonExistent.new(template_name) unless File.exists?(path)
|
44
|
+
@template ||= File.read(path)
|
45
|
+
end
|
46
|
+
|
47
|
+
def template_name
|
48
|
+
raise 'Not Implemented!'
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module PivotalDoc
|
2
|
+
module Generators
|
3
|
+
class HTML < Base
|
4
|
+
def template_name
|
5
|
+
@options[:template_name] || 'html_gen.haml'
|
6
|
+
end
|
7
|
+
def output_ext; '.html' end
|
8
|
+
def render_doc
|
9
|
+
html= Haml::Engine.new(template).render(Object.new, {:release=>@release})
|
10
|
+
super(html)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module PivotalDoc
|
2
|
+
class Release
|
3
|
+
attr_reader :project
|
4
|
+
attr_reader :iteration
|
5
|
+
|
6
|
+
def initialize(project, iteration=nil)
|
7
|
+
@project= project
|
8
|
+
@iteration= (iteration || latest_iteration)
|
9
|
+
end
|
10
|
+
|
11
|
+
def me
|
12
|
+
@me ||= self.iteration.stories.detect{|s| s.story_type.downcase=='release'} if self.iteration.stories
|
13
|
+
end
|
14
|
+
|
15
|
+
def name
|
16
|
+
me.name if me.respond_to?(:name)
|
17
|
+
end
|
18
|
+
|
19
|
+
def project_name
|
20
|
+
@project.name
|
21
|
+
end
|
22
|
+
|
23
|
+
def latest_iteration
|
24
|
+
PT::Iteration.done(@project, :offset=>'-1').first
|
25
|
+
end
|
26
|
+
|
27
|
+
def stories
|
28
|
+
@stories ||= filter_stories
|
29
|
+
end
|
30
|
+
|
31
|
+
def bugs
|
32
|
+
@bugs ||= filter_stories('bug')
|
33
|
+
end
|
34
|
+
|
35
|
+
def chores
|
36
|
+
@chores ||= filter_stories('chore')
|
37
|
+
end
|
38
|
+
|
39
|
+
[:stories, :bugs, :chores].each do |m|
|
40
|
+
define_method("#{m}_delivered") { self.send(m).size }
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
def filter_stories(type='feature')
|
45
|
+
self.iteration.stories.reject do |s|
|
46
|
+
s.story_type.downcase != type || s.current_state.downcase != 'accepted'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/pivotal_doc.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'yaml'
|
3
|
+
require 'pivotal-tracker'
|
4
|
+
require 'haml'
|
5
|
+
PT= PivotalTracker unless defined?(PT)
|
6
|
+
PROJECT_ROOT= File.join(File.dirname(__FILE__), '/../') unless defined?(PROJECT_ROOT)
|
7
|
+
|
8
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'../ext','**','*.rb'))].each {|f| require f}
|
9
|
+
Dir[File.expand_path(File.join(File.dirname(__FILE__),'pivotal_doc/','**','*.rb'))].each {|f| require f}
|
10
|
+
|
11
|
+
if ENV['mode'] == 'test'
|
12
|
+
require 'spec'
|
13
|
+
require 'spec/autorun'
|
14
|
+
end
|
data/pivotal_doc.gemspec
ADDED
@@ -0,0 +1,106 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{pivotal_doc}
|
8
|
+
s.version = "1.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Tim Linquist"]
|
12
|
+
s.date = %q{2010-10-29}
|
13
|
+
s.description = %q{
|
14
|
+
Automated release notes for apps hosted on pivotaltracker.com.
|
15
|
+
Allows release notes to be generated for any project on pivotaltracker.com by retrieving the latest iteration for the specified project and displaying the completed features, bugs, and chores.
|
16
|
+
}
|
17
|
+
s.email = %q{tim.linquist@gmail.com}
|
18
|
+
s.extra_rdoc_files = [
|
19
|
+
"README"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".gitignore",
|
23
|
+
"README",
|
24
|
+
"Rakefile",
|
25
|
+
"VERSION",
|
26
|
+
"assets/css/ui-lightness/images/ui-bg_diagonals-thick_18_b81900_40x40.png",
|
27
|
+
"assets/css/ui-lightness/images/ui-bg_diagonals-thick_20_666666_40x40.png",
|
28
|
+
"assets/css/ui-lightness/images/ui-bg_flat_10_000000_40x100.png",
|
29
|
+
"assets/css/ui-lightness/images/ui-bg_glass_100_f6f6f6_1x400.png",
|
30
|
+
"assets/css/ui-lightness/images/ui-bg_glass_100_fdf5ce_1x400.png",
|
31
|
+
"assets/css/ui-lightness/images/ui-bg_glass_65_ffffff_1x400.png",
|
32
|
+
"assets/css/ui-lightness/images/ui-bg_gloss-wave_35_f6a828_500x100.png",
|
33
|
+
"assets/css/ui-lightness/images/ui-bg_highlight-soft_100_eeeeee_1x100.png",
|
34
|
+
"assets/css/ui-lightness/images/ui-bg_highlight-soft_75_ffe45c_1x100.png",
|
35
|
+
"assets/css/ui-lightness/images/ui-icons_222222_256x240.png",
|
36
|
+
"assets/css/ui-lightness/images/ui-icons_228ef1_256x240.png",
|
37
|
+
"assets/css/ui-lightness/images/ui-icons_ef8c08_256x240.png",
|
38
|
+
"assets/css/ui-lightness/images/ui-icons_ffd27a_256x240.png",
|
39
|
+
"assets/css/ui-lightness/images/ui-icons_ffffff_256x240.png",
|
40
|
+
"assets/css/ui-lightness/jquery-ui-1.8.5.custom.css",
|
41
|
+
"assets/js/jquery-1.4.2.min.js",
|
42
|
+
"assets/js/jquery-ui-1.8.5.custom.min.js",
|
43
|
+
"ext/date.rb",
|
44
|
+
"lib/pivotal_doc.rb",
|
45
|
+
"lib/pivotal_doc/configuration.rb",
|
46
|
+
"lib/pivotal_doc/exceptions.rb",
|
47
|
+
"lib/pivotal_doc/generator.rb",
|
48
|
+
"lib/pivotal_doc/generators/base.rb",
|
49
|
+
"lib/pivotal_doc/generators/html.rb",
|
50
|
+
"lib/pivotal_doc/generators/text.rb",
|
51
|
+
"lib/pivotal_doc/release.rb",
|
52
|
+
"pivotal_doc.gemspec",
|
53
|
+
"spec/fixtures/configs.yml",
|
54
|
+
"spec/fixtures/iterations.yml",
|
55
|
+
"spec/fixtures/projects.yml",
|
56
|
+
"spec/fixtures/stories.yml",
|
57
|
+
"spec/lib/configuration_spec.rb",
|
58
|
+
"spec/lib/generator_spec.rb",
|
59
|
+
"spec/lib/generators/base_spec.rb",
|
60
|
+
"spec/lib/generators/html_spec.rb",
|
61
|
+
"spec/lib/generators/text_spec.rb",
|
62
|
+
"spec/lib/release_spec.rb",
|
63
|
+
"spec/spec_helper.rb",
|
64
|
+
"spec/support/mocks_helper.rb",
|
65
|
+
"spec/support/pt_api_helpers.rb",
|
66
|
+
"templates/fancy.haml",
|
67
|
+
"templates/html_gen.haml",
|
68
|
+
"templates/text_gen.txt"
|
69
|
+
]
|
70
|
+
s.homepage = %q{http://github.com/timo3377/pivotal_doc}
|
71
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
72
|
+
s.require_paths = ["lib"]
|
73
|
+
s.rubygems_version = %q{1.3.7}
|
74
|
+
s.summary = %q{A release documentation generator for pivotaltracker.com}
|
75
|
+
s.test_files = [
|
76
|
+
"spec/lib/configuration_spec.rb",
|
77
|
+
"spec/lib/generator_spec.rb",
|
78
|
+
"spec/lib/generators/base_spec.rb",
|
79
|
+
"spec/lib/generators/html_spec.rb",
|
80
|
+
"spec/lib/generators/text_spec.rb",
|
81
|
+
"spec/lib/release_spec.rb",
|
82
|
+
"spec/spec_helper.rb",
|
83
|
+
"spec/support/mocks_helper.rb",
|
84
|
+
"spec/support/pt_api_helpers.rb"
|
85
|
+
]
|
86
|
+
|
87
|
+
if s.respond_to? :specification_version then
|
88
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
89
|
+
s.specification_version = 3
|
90
|
+
|
91
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
92
|
+
s.add_runtime_dependency(%q<pivotal-tracker>, [">= 0.2.1"])
|
93
|
+
s.add_runtime_dependency(%q<haml>, [">= 0"])
|
94
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
95
|
+
else
|
96
|
+
s.add_dependency(%q<pivotal-tracker>, [">= 0.2.1"])
|
97
|
+
s.add_dependency(%q<haml>, [">= 0"])
|
98
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
99
|
+
end
|
100
|
+
else
|
101
|
+
s.add_dependency(%q<pivotal-tracker>, [">= 0.2.1"])
|
102
|
+
s.add_dependency(%q<haml>, [">= 0"])
|
103
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
@@ -0,0 +1,11 @@
|
|
1
|
+
- account: Awesome Guys
|
2
|
+
current_velocity: 3
|
3
|
+
id: 42411
|
4
|
+
initial_velocity: 4
|
5
|
+
iteration_length: 3
|
6
|
+
last_activity_at: 2010-09-16T19:41:29+00:00
|
7
|
+
name: My Hotness
|
8
|
+
point_scale: "0,1,2,3"
|
9
|
+
use_https: false
|
10
|
+
velocity_scheme: Average of 3 iterations
|
11
|
+
week_start_day: Tuesday
|
@@ -0,0 +1,87 @@
|
|
1
|
+
- accepted_at: 2010-08-30T16:14:23+00:00
|
2
|
+
attachments: []
|
3
|
+
created_at: 2010-08-05T18:09:40+00:00
|
4
|
+
current_state: Delivered
|
5
|
+
description: Deploy core component of app to staging.
|
6
|
+
estimate: 2
|
7
|
+
id: 1
|
8
|
+
integration_id:
|
9
|
+
jira_id:
|
10
|
+
jira_url:
|
11
|
+
labels:
|
12
|
+
name: Create staging env for app
|
13
|
+
other_id:
|
14
|
+
owned_by: Tim Linquist
|
15
|
+
project_id: 42411
|
16
|
+
requested_by: Tim Linquist
|
17
|
+
story_type: feature
|
18
|
+
url: http://www.pivotaltracker.com/story/show/1,
|
19
|
+
|
20
|
+
- created_at: 2010-08-06T19:46:38+00:00
|
21
|
+
current_state: accepted
|
22
|
+
description:
|
23
|
+
estimate: 1
|
24
|
+
id: 2
|
25
|
+
integration_id:
|
26
|
+
jira_id:
|
27
|
+
jira_url:
|
28
|
+
labels:
|
29
|
+
name: Eliminate Bots from app
|
30
|
+
other_id:
|
31
|
+
owned_by: Tim Linquist
|
32
|
+
project_id: 42411
|
33
|
+
requested_by: Tim Linquist
|
34
|
+
story_type: feature
|
35
|
+
url: http://www.pivotaltracker.com/story/show/2
|
36
|
+
|
37
|
+
- created_at: 2010-08-06T19:46:38+00:00
|
38
|
+
current_state: accepted
|
39
|
+
description: MongoDB server
|
40
|
+
estimate: 2
|
41
|
+
id: 3
|
42
|
+
integration_id:
|
43
|
+
jira_id:
|
44
|
+
jira_url:
|
45
|
+
labels:
|
46
|
+
name: Mongo Master host
|
47
|
+
other_id:
|
48
|
+
owned_by: Tim Linquist
|
49
|
+
project_id: 42411
|
50
|
+
requested_by: Tim Linquist
|
51
|
+
story_type: chore
|
52
|
+
url: http://www.pivotaltracker.com/story/show/3
|
53
|
+
|
54
|
+
- created_at: 2010-08-06T19:46:38+00:00
|
55
|
+
current_state: accepted
|
56
|
+
description: The app isn't working
|
57
|
+
estimate: 2
|
58
|
+
id: 4
|
59
|
+
integration_id:
|
60
|
+
jira_id:
|
61
|
+
jira_url:
|
62
|
+
labels:
|
63
|
+
name: The app needs to work better than it does
|
64
|
+
other_id:
|
65
|
+
owned_by: Tim Linquist
|
66
|
+
project_id: 42411
|
67
|
+
requested_by: Tim Linquist
|
68
|
+
story_type: bug
|
69
|
+
url: http://www.pivotaltracker.com/story/show/4
|
70
|
+
|
71
|
+
- created_at: 2010-08-06T19:46:38+00:00
|
72
|
+
current_state: Not Yet Started
|
73
|
+
description:
|
74
|
+
estimate:
|
75
|
+
id: 5
|
76
|
+
integration_id:
|
77
|
+
jira_id:
|
78
|
+
jira_url:
|
79
|
+
labels:
|
80
|
+
name: Grateful Dead Sprint
|
81
|
+
other_id:
|
82
|
+
owned_by: Project Owner
|
83
|
+
project_id: 42411
|
84
|
+
requested_by: Product Manager
|
85
|
+
story_type: release
|
86
|
+
url: http://www.pivotaltracker.com/story/show/5
|
87
|
+
|
@@ -0,0 +1,88 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe PivotalDoc::Configuration do
|
4
|
+
before(:each) do
|
5
|
+
@connection= PivotalDoc::Connection.new('A18das1', 'radical', 'dude')
|
6
|
+
@config= PivotalDoc::Configuration.new(File.join(File.dirname(__FILE__), '/../fixtures/', 'configs.yml'))
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should load the settings from the file" do
|
10
|
+
@config.settings.should be_an_instance_of(Hash)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should load the settings from the options" do
|
14
|
+
settings= {:test=>'parameter'}
|
15
|
+
config= PivotalDoc::Configuration.new(settings)
|
16
|
+
config.settings.should eql(settings)
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "Authenticating" do
|
20
|
+
before(:each) do
|
21
|
+
@config.instance_variable_set(:@connection, @connection)
|
22
|
+
end
|
23
|
+
|
24
|
+
after(:each) do
|
25
|
+
@config.instance_variable_set(:@authenticated, false)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should set the token if it's configured" do
|
29
|
+
PT::Client.should_receive(:token=).with(@connection.token)
|
30
|
+
@config.authenticate!
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should set the token via the username & password if the token isn't configured" do
|
34
|
+
@connection.token= nil
|
35
|
+
PT::Client.should_receive(:token).with(@connection.username, @connection.password)
|
36
|
+
@config.authenticate!
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should not set the token again if the client is already authenticated" do
|
40
|
+
PT::Client.should_receive(:token=).exactly(:once)
|
41
|
+
@config.authenticate!
|
42
|
+
@config.authenticate!
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "A Project" do
|
47
|
+
before(:each) do
|
48
|
+
@projects= @config.projects
|
49
|
+
@project= @projects.fetch(@projects.keys.first)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should know all of the projects" do
|
53
|
+
@projects.should_not be_empty
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should know the members" do
|
57
|
+
@project['members'].should be_an_instance_of(Array)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "should know its id" do
|
61
|
+
@project['id'].should be_an_instance_of(Fixnum)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "Connection" do
|
66
|
+
after(:each) do
|
67
|
+
@config.instance_variable_set(:@connection, nil)
|
68
|
+
end
|
69
|
+
|
70
|
+
[:token, :username, :password].each do |property|
|
71
|
+
connection= PivotalDoc::Connection.new
|
72
|
+
it "should have the #{property} property" do
|
73
|
+
connection.should respond_to(property)
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should not redefine the connection" do
|
78
|
+
PivotalDoc::Connection.should_receive(:new).exactly(:once).and_return(@connection)
|
79
|
+
@config.send(:connection)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should default to the config.yml settings" do
|
83
|
+
%w(token username password).each do |_attr|
|
84
|
+
@config.send(:connection).send(_attr.to_sym).should eql(@config.settings[_attr])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper'
|
2
|
+
|
3
|
+
describe PivotalDoc::Generator do
|
4
|
+
before(:each) do
|
5
|
+
@config= PivotalDoc::Configuration.new(File.join(File.dirname(__FILE__), '/../fixtures/', 'configs.yml'))
|
6
|
+
PivotalDoc::Configuration.stub!(:new).and_return(@config)
|
7
|
+
PivotalDoc::Generator.generators.values.each do |g|
|
8
|
+
generator= mock(g.to_s)
|
9
|
+
g.stub!(:new).and_return(generator)
|
10
|
+
generator.stub!(:render_doc)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "Configuring" do
|
15
|
+
before(:each) do
|
16
|
+
PivotalDoc::Generator.stub!(:collect_releases!)
|
17
|
+
PivotalDoc::Generator.releases= []
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should create a config object from the settings" do
|
21
|
+
settings= {}
|
22
|
+
@config.stub!(:authenticate!)
|
23
|
+
PivotalDoc::Configuration.should_receive(:new).with(settings).and_return(@config)
|
24
|
+
PivotalDoc::Generator.generate(:html, settings)
|
25
|
+
PivotalDoc::Generator.config.should eql(@config)
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should authenticate against pivotal before generating the release docs" do
|
29
|
+
@config.should_receive(:authenticate!)
|
30
|
+
PivotalDoc::Generator.generate(:html)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe "generation" do
|
35
|
+
before(:each) do
|
36
|
+
@config.stub!(:authenticate!).and_return(true)
|
37
|
+
@release= mocks_helper(:release)
|
38
|
+
PT::Project.stub!(:find).and_return(@release.project)
|
39
|
+
PivotalDoc::Release.stub!(:new).and_return(@release)
|
40
|
+
end
|
41
|
+
|
42
|
+
describe "Formattting" do
|
43
|
+
before(:each) do
|
44
|
+
@options={:my_custom_option=>'my custom value'}
|
45
|
+
@html_gen= PivotalDoc::Generators::HTML.new({})
|
46
|
+
@html_gen.stub!(:render_doc)
|
47
|
+
end
|
48
|
+
it "should render the release with the specified format and custom settings" do
|
49
|
+
PivotalDoc::Generators::HTML.should_receive(:new).with(@release, @config.settings).and_return(@html_gen)
|
50
|
+
PivotalDoc::Generator.generate(:html)
|
51
|
+
end
|
52
|
+
it "should raise an error if the specified format isn't supported" do
|
53
|
+
lambda{ PivotalDoc::Generator.generate(:unsupported) }.should raise_error(PivotalDoc::FormatNotSupported)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../spec_helper'
|
2
|
+
|
3
|
+
describe PivotalDoc::Generators::Base do
|
4
|
+
before(:each) do
|
5
|
+
@release= mocks_helper(:release)
|
6
|
+
@base= PivotalDoc::Generators::Base.new(@release)
|
7
|
+
end
|
8
|
+
it "should raise an exception if the template doesn't exist" do
|
9
|
+
@base.stub!(:template_name).and_return('non-existent.txt')
|
10
|
+
lambda{@base.template}.should raise_error(PivotalDoc::TemplateNonExistent)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "Rendering the doc" do
|
14
|
+
before(:each) do
|
15
|
+
@base.stub!(:template).and_return('index.txt')
|
16
|
+
end
|
17
|
+
|
18
|
+
after(:each) do
|
19
|
+
File.delete(@base.output_file) if File.exists?(@base.output_file)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "options" do
|
23
|
+
it "should be a fully qualified file" do
|
24
|
+
base= PivotalDoc::Generators::Base.new(@release, {:output_file=>'my_file'})
|
25
|
+
f= File.open(base.output_file, 'w')
|
26
|
+
f.should be_an_instance_of(File)
|
27
|
+
File.delete(f.path)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should use the output_file if present" do
|
31
|
+
base= PivotalDoc::Generators::Base.new(@release, {'output_file'=>'my_file'})
|
32
|
+
base.output_file.should =~ /\/my_file/
|
33
|
+
end
|
34
|
+
|
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}/
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should use the output_path if present" do
|
41
|
+
base= PivotalDoc::Generators::Base.new(@release, {'output_path'=>'my_path'})
|
42
|
+
base.output_path.should =~ /^my_path/
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should default the output_path to the relative directory" do
|
46
|
+
base= PivotalDoc::Generators::Base.new(@release)
|
47
|
+
base.output_path.should =~ /^#{base.absolute_path}/
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should open the output file and write the output" do
|
52
|
+
output= 'My custom output'
|
53
|
+
@base.render_doc(output)
|
54
|
+
File.read(@base.output_file).should eql(output)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should handle any exceptions and output STDOUT" do
|
58
|
+
File.stub!(:open).and_raise(Exception.new('A MAJOR CATASTROPHE'))
|
59
|
+
$stdout.should_receive(:print).with('A MAJOR CATASTROPHE')
|
60
|
+
$stdout.should_receive(:flush)
|
61
|
+
@base.render_doc
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|