tps_reporter 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: d21f4bd77a71d9c987856ac5f0f584704749296a
4
+ data.tar.gz: cc243b6990b860aa4c8891ab2394a88e02bd6eff
5
+ SHA512:
6
+ metadata.gz: 7b773a7577899cb5e6fb9441e4d7820f7390306a4d0de6f7491ec3481184b31d37bfa7363dd5142c577f7f6b1b69136c4ecfa0648854e470d5cc271ff17f1990
7
+ data.tar.gz: 7691a2a6ef3f16dfe6fafe767c45535d638056b060bae90edb6c0258ad9924dd56a360b853e21fad62729d106f57735459dcf357caf52f1c89b4c8bc47e547fb
data/HISTORY.md CHANGED
@@ -1,3 +1,8 @@
1
+ v0.3.0 - June 13, 2013
2
+ ----------------------
3
+
4
+ * Sprint support
5
+
1
6
  v0.2.2 - Dec 23, 2012
2
7
  ---------------------
3
8
 
data/Notes.md ADDED
@@ -0,0 +1,14 @@
1
+ Development notes
2
+ -----------------
3
+
4
+ Releasing the gem:
5
+
6
+ $ vim lib/tps/version.rb # Bump version
7
+ $ git clog # Mini utility to write changelog
8
+ $ vim HISTORY.md # Fix up changelog
9
+ $ git release v0.X.X # github.com/visionmedia/git-extras
10
+ $ rake test
11
+
12
+ $ rm *.gem
13
+ $ gem build *.gemspec
14
+ $ gem push *.gem
data/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Task progress sheet reporter
2
2
 
3
- ![TPS report](https://img.skitch.com/20120203-nr24dn9u7euchmqa516718unpe.png)
3
+ ![TPS report](http://i.imgur.com/AA7LNTR.png)
4
4
 
5
5
  We often need to make regular reports of things done for our projects at work. I
6
6
  hate doing these by hand. This tool lets us build these reports from YAML files
@@ -86,17 +86,3 @@ looks like this:
86
86
  ![Comamnd line reporter][cli]
87
87
 
88
88
  [cli]: https://img.skitch.com/20120204-ccb2guerhrjmj3rht3e4ies4ur.png
89
-
90
- Development notes
91
- -----------------
92
-
93
- Releasing the gem:
94
-
95
- $ vim lib/tps/version.rb # Bump version
96
- $ git clog # Mini utility to write changelog
97
- $ vim HISTORY.md # Fix up changelog
98
- $ git release v0.X.X # github.com/visionmedia/git-extras
99
-
100
- $ rm *.gem
101
- $ gem build *.gemspec
102
- $ gem push *.gem
data/data/index.haml CHANGED
@@ -72,8 +72,7 @@
72
72
  border-collapse: collapse; }
73
73
 
74
74
  table td, table th {
75
- padding: 5px 10px;
76
- border-top: solid 1px #eee; }
75
+ padding: 5px 10px; }
77
76
 
78
77
  /* Columns */
79
78
  tr>.task { width: auto; text-align: left; padding-right: 50px; }
@@ -225,33 +224,41 @@
225
224
  display: block;
226
225
  float: left;
227
226
 
228
- background-color: #eee;
229
- background: -webkit-linear-gradient(left, #eee, #ddd);
230
- height: 2px;
227
+ height: 1px;
231
228
  border-top-left-radius: 1px;
232
229
  border-bottom-left-radius: 1px;
233
230
  margin-top: 8px; }
234
231
 
232
+ .sprint-progress {
233
+ background-color: #eee; }
234
+ .sprint-progress:first-child {
235
+ background: -webkit-linear-gradient(left, #eee, #ddd); }
236
+ .sprint-progress:last-child {
237
+ background: -webkit-linear-gradient(left, #ddd, #eee); }
238
+
235
239
  .sprint-marker {
236
240
  display: block;
237
241
  float: left;
238
242
 
239
243
  background: #ccc;
240
244
 
241
- width: 6px;
242
- height: 6px;
243
- border-radius: 3px;
245
+ min-width: 6px;
246
+ height: 12px;
247
+ line-height: 11px;
248
+ border-radius: 6px;
244
249
  float: left;
245
250
 
246
- margin-top: 6px; }
251
+ font-size: 7pt;
252
+ font-weight: bold;
253
+ color: #777;
247
254
 
248
- .sprint-label {
249
- display: block;
250
- float: left;
255
+ text-shadow: 0 1px 0 rgba(255, 255, 255, 0.4);
256
+ text-align: center;
251
257
 
252
- font-size: 7pt;
253
- color: #888;
254
- padding-left: 5px; }
258
+ margin-top: 3px; }
259
+
260
+ .sprint-marker .dash {
261
+ opacity: 0.5; }
255
262
 
256
263
  .status-bg-in_progress {
257
264
  background: #ea3; }
@@ -259,6 +266,11 @@
259
266
  .status-bg-done {
260
267
  background: #393; }
261
268
 
269
+ .status-bg-done,
270
+ .status-bg-in_progress {
271
+ color: white;
272
+ text-shadow: 0 1px 0 rgba(0, 0, 0, 0.3), 0 1px 2px rgba(0, 0, 0, 0.4); }
273
+
262
274
  /* Navigation */
263
275
  body {
264
276
  padding: 80px 0 50px 0; }
@@ -438,12 +450,25 @@
438
450
 
439
451
  - if list.sprints?
440
452
  %td.sprints
441
- - if task.sprint?
453
+ - bar = TPS::BarFormatter.new(task)
454
+ - if bar.visible?
455
+
442
456
  %span.sprint-display
443
- %span.sprint-progress{style: "width: #{45*task.sprint.index+6}px"}
444
- %span.sprint-marker{class: "status-bg-#{task.status}"}
445
- %span.sprint-label
446
- = task.sprint.id
457
+ - bar.segments.each do |type, (size, sprints)|
458
+ - if type == :line
459
+ %span.sprint-progress{style: "width: #{size}px"}
460
+ - elsif type == :marker
461
+ %span.sprint-marker{class: "status-bg-#{task.status}", style: "width: #{size}px"}
462
+ - if sprints.length > 1
463
+ = sprints.first.id
464
+ %span.dash<>= "&ndash;"
465
+ = sprints.last.id
466
+
467
+ - else
468
+ = sprints.first.id
469
+
470
+ -# %span.sprint-label
471
+ -# = bar.label
447
472
 
448
473
  %td.progress
449
474
  .bar
@@ -0,0 +1,93 @@
1
+ module TPS
2
+ # Presenter for tasks to format things into bars.
3
+ class BarFormatter
4
+ attr_reader :task
5
+
6
+ def initialize(task)
7
+ @task = task
8
+ end
9
+
10
+ # Array of sprints.
11
+ def sprints
12
+ @sprints ||= task.sprints
13
+ end
14
+
15
+ def all_sprints
16
+ @all_sprints ||= @task.list.sprints.values
17
+ end
18
+
19
+ # Returns segments of the indices of sprints.
20
+ def index_segments
21
+ to_segments(sprints.map(&:index))
22
+ end
23
+
24
+ def visible?
25
+ sprints.any?
26
+ end
27
+
28
+ # Returns segments. Lines are in the format:
29
+ #
30
+ # |type, (size, sprints)|
31
+ #
32
+ def segments
33
+ re = Array.new
34
+
35
+ last_max = -1
36
+
37
+ segs = index_segments
38
+ segs.each_with_index do |range, i|
39
+ sprints = range.to_a.map { |i| all_sprints[i] }
40
+ span = range.max - range.min + 1
41
+ w = range.min-last_max-1
42
+
43
+ line_length = segment_width * w + inner_pad
44
+
45
+ marker_length = segment_width * span - inner_pad
46
+
47
+ re << [ :line, [line_length, sprints] ]
48
+ re << [ :marker, [marker_length, sprints] ]
49
+
50
+ last_max = range.max
51
+ end
52
+
53
+ # Last line
54
+ butal = all_sprints.length - sprints.last.index - 1
55
+ re << [ :line, segment_width * butal + inner_pad ]
56
+
57
+ re
58
+ end
59
+
60
+ def label
61
+ sprints.map(&:id).join(" ")
62
+ end
63
+
64
+ private
65
+
66
+ def segment_width() 35; end
67
+ def inner_pad() 12; end
68
+
69
+ # Connects an array of numeric indices. Returns an array of ranges.
70
+ #
71
+ # to_segments([2,3,4,5,6,14,15])
72
+ # #=> [ (2..6), (14..15) ]
73
+ #
74
+ def to_segments(indexes)
75
+ segments = Array.new
76
+
77
+ ([-1] + indexes).each_cons(2) do |prev, i|
78
+ if prev == -1
79
+ segments << (i..i)
80
+ prev = i-1
81
+ end
82
+ if prev.next == i
83
+ segments[segments.length-1] = ((segments[segments.length-1].min)..i)
84
+ else
85
+ segments << (i..i)
86
+ end
87
+ end
88
+
89
+ segments
90
+ end
91
+
92
+ end
93
+ end
data/lib/tps/sprint.rb CHANGED
@@ -39,6 +39,14 @@ module TPS
39
39
  slugify id
40
40
  end
41
41
 
42
+ def inspect
43
+ '#<%s %s ("%s")>' % [ self.class.name, id, name ]
44
+ end
45
+
46
+ def to_s
47
+ inspect
48
+ end
49
+
42
50
  private
43
51
 
44
52
  def slugify(str)
data/lib/tps/task.rb CHANGED
@@ -59,14 +59,13 @@ module TPS
59
59
  @tags.push t[1..-1]
60
60
  # Sprint name
61
61
  elsif list && list.sprints[t]
62
- @sprint = list.sprints[t]
62
+ @sprints ||= Array.new
63
+ @sprints << list.sprints[t]
63
64
  end
64
65
  end
65
66
 
66
67
  @tasks = tasks.map { |task, data| Task.new self, task, data, self.list } if tasks
67
68
 
68
- @milestone = root? && is_milestone?(@name)
69
-
70
69
  @id = list.get_id if list
71
70
  end
72
71
 
@@ -96,7 +95,7 @@ module TPS
96
95
  def points_for(sprint)
97
96
  if tasks?
98
97
  tasks.inject(0.0) { |pts, task| pts + task.points_for(sprint) }
99
- elsif sprint? && self.sprint.id == sprint.id
98
+ elsif sprints? && self.sprints.include?(sprint)
100
99
  @points || 1.0
101
100
  else
102
101
  0
@@ -135,16 +134,22 @@ module TPS
135
134
  tasks.any?
136
135
  end
137
136
 
138
- def sprint?
139
- !! sprint
137
+ def sprints?
138
+ sprints.any?
140
139
  end
141
140
 
142
- def sprint
143
- @sprint || (parent && parent.sprint)
141
+ def sprints
142
+ if @sprints
143
+ @sprints
144
+ elsif parent
145
+ parent.sprints
146
+ else
147
+ Array.new
148
+ end
144
149
  end
145
150
 
146
151
  def contains_sprint?(sprint)
147
- contains? { |t| t.sprint == sprint }
152
+ contains? { |t| t.sprints.include?(sprint) }
148
153
  end
149
154
 
150
155
  # Filters a task list by tasks that match a given block, preserving its
@@ -187,7 +192,7 @@ module TPS
187
192
  ('feature' if feature?),
188
193
  ('milestone' if milestone?),
189
194
  ('subtask' if subtask?),
190
- ("sprint-#{sprint.slug}" if sprint?),
195
+ (sprints.map { |s| "sprint-#{s.slug}" } if sprints?),
191
196
  sprint_css_classes,
192
197
  breadcrumbs(false).map { |t| "in_task_#{t.id}" }
193
198
  ].flatten.compact.join(' ')
@@ -204,7 +209,7 @@ module TPS
204
209
  end
205
210
 
206
211
  def filter_by_sprint(sprint)
207
- filter { |t| t.sprint == sprint }
212
+ filter { |t| t.sprints.include?(sprint) }
208
213
  end
209
214
 
210
215
  # Works like #filter, but only preserves ancestors if they match.
@@ -263,8 +268,21 @@ module TPS
263
268
  root? or parent.milestone?
264
269
  end
265
270
 
271
+ # Finds a task named `name` in the task's descendants.
272
+ # Returns a `Task` instance.
273
+ #
274
+ # list.find("Login")
275
+ #
276
+ # # Accounts:
277
+ # # Login:
278
+ #
279
+ def find(name)
280
+ return self if name == self.name
281
+ tasks.inject(nil) { |result, task| result || task.find(name) }
282
+ end
283
+
266
284
  def milestone?
267
- !! @milestone
285
+ level == 0
268
286
  end
269
287
 
270
288
  def leaf?
@@ -312,13 +330,9 @@ module TPS
312
330
  str
313
331
  end
314
332
 
315
- private
316
-
317
- def is_milestone?(str)
318
- str = str.to_s.downcase
319
- str.match(/^milestone|milestone$/i) ||
320
- str.match(/^release|release$/i) ||
321
- str.match(/^version|version$/i)
333
+ # Returns the presenter
334
+ def bar_formatter
335
+ TPS::BarFormatter.new self
322
336
  end
323
337
  end
324
338
  end
data/lib/tps/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  module TPS
2
2
  def self.version
3
- "0.2.2"
3
+ "0.3.0"
4
4
  end
5
5
  end
data/lib/tps.rb CHANGED
@@ -22,10 +22,11 @@ require 'tilt'
22
22
  module TPS
23
23
  ROOT = File.expand_path('../../', __FILE__)
24
24
 
25
- autoload :Task, 'tps/task'
26
- autoload :TaskList, 'tps/task_list'
27
- autoload :CliReporter, 'tps/cli_reporter'
28
- autoload :Sprint, 'tps/sprint'
25
+ autoload :Task, 'tps/task'
26
+ autoload :TaskList, 'tps/task_list'
27
+ autoload :CliReporter, 'tps/cli_reporter'
28
+ autoload :Sprint, 'tps/sprint'
29
+ autoload :BarFormatter, 'tps/bar_formatter'
29
30
 
30
31
  require 'tps/version'
31
32
 
data/test/bar_test.rb ADDED
@@ -0,0 +1,47 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class BarTest < UnitTest
4
+ setup do
5
+ @list = TPS::TaskList.new yaml: f('markers.yml')
6
+ @milestone = @list.tasks.first
7
+
8
+ @week = %w[w0 w1 w2 w3 w4 w5 w6].map { |id| @list.sprints[id] }
9
+ end
10
+
11
+ test "basic sanity check" do
12
+ assert_equal 2, @list.find("Login").sprints.length
13
+ end
14
+
15
+ context "#index_segments" do
16
+ test "disjointed" do
17
+ task = @list.find("Disjointed")
18
+ bar = task.bar_formatter
19
+ assert_equal [(1..2), (4..4)], bar.index_segments
20
+ end
21
+
22
+ test "continuous" do
23
+ task = @list.find("Continuous")
24
+ bar = task.bar_formatter
25
+ assert_equal [(1..4)], bar.index_segments
26
+ end
27
+
28
+ test "disjointed with head" do
29
+ task = @list.find("Disjointed with head")
30
+ bar = task.bar_formatter
31
+ assert_equal [(1..1), (3..4)], bar.index_segments
32
+ end
33
+
34
+ test "disjointed with two segments" do
35
+ task = @list.find("Disjointed with two segments")
36
+ bar = task.bar_formatter
37
+ assert_equal [(2..3), (5..6)], bar.index_segments
38
+ end
39
+ end
40
+
41
+ context "#segments" do
42
+ test "disjointed" do
43
+ task = @list.find("Disjointed")
44
+ bar = task.bar_formatter
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,20 @@
1
+
2
+ Sprints:
3
+ w0: Week 0
4
+ w1: Week 1
5
+ w2: Week 2
6
+ w3: Week 3
7
+ w4: Week 4
8
+ w5: Week 5
9
+ w6: Week 6
10
+
11
+ Tests:
12
+ Account management:
13
+ Login: [w2, w3]
14
+ Signup: [w3, 5pts]
15
+
16
+ Segments:
17
+ Disjointed: [w1, w2, w4]
18
+ Disjointed with head: [w1, w3, w4, 50%]
19
+ Continuous: [w1, w2, w3, w4]
20
+ Disjointed with two segments: [w2, w3, w5, w6]
@@ -0,0 +1,10 @@
1
+ Sprints:
2
+ w1: Week 1
3
+ w2: Week 2
4
+ w3: Week 3
5
+ w4: Week 4
6
+
7
+ Account management:
8
+ Login: [w1, w2]
9
+ Signup: [w1, 5pts]
10
+ Register: [w2]
data/test/html_test.rb ADDED
@@ -0,0 +1,19 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class HtmlTest < UnitTest
4
+ TESTS = %w[hello.yml multi_sprints.yml sprint_points.yml sprints.yml]
5
+
6
+ TESTS.each do |yml_file|
7
+ context yml_file do
8
+ setup do
9
+ @list = TPS::TaskList.new yaml: f(yml_file)
10
+ end
11
+
12
+ test "HTML" do
13
+ html = @list.to_html
14
+ assert html.include?("span")
15
+ assert html.include?("body")
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,26 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class MultiSprintsTest < UnitTest
4
+ setup do
5
+ @list = TPS::TaskList.new yaml: f('multi_sprints.yml')
6
+ @milestone = @list.tasks.first
7
+
8
+ @week = %w[_ w1 w2 w3 w4].map { |id| @list.sprints[id] }
9
+ end
10
+
11
+ test "Sprints" do
12
+ sprints = @list.find('Login').sprints
13
+
14
+ assert_equal 2, sprints.length
15
+ assert sprints.include?(@week[1])
16
+ assert sprints.include?(@week[2])
17
+ end
18
+
19
+ test "points (1)" do
20
+ assert_equal 6, @week[1].points
21
+ end
22
+
23
+ test "points (2)" do
24
+ assert_equal 2, @week[2].points
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class SprintPointsTest < UnitTest
4
+ setup do
5
+ @list = TPS::TaskList.new yaml: f('sprint_points.yml')
6
+ @milestone = @list.tasks.first
7
+ @s = %w[_ s1 s2 s3 s4 s5].map { |id| @list.sprints[id] }
8
+ end
9
+
10
+ test "S1 points" do
11
+ assert_equal 1.0, @s[1].points
12
+ end
13
+
14
+ test "S2 points" do
15
+ assert_equal 3.0, @s[2].points
16
+ end
17
+
18
+ test "S3 points" do
19
+ assert_equal 0.0, @s[3].points
20
+ end
21
+
22
+ test "S4 points" do
23
+ assert_equal 2.5, @s[4].points
24
+ end
25
+
26
+ test "S5 points" do
27
+ assert_equal 1.0, @s[5].points
28
+ end
29
+ end
data/test/sprint_test.rb CHANGED
@@ -1,92 +1,62 @@
1
1
  require File.expand_path('../test_helper', __FILE__)
2
2
 
3
3
  class SprintTest < UnitTest
4
- context "Basic sprints" do
5
- setup do
6
- @list = TPS::TaskList.new yaml: f('sprints.yml')
7
- @milestone = @list.tasks.first
8
- @s1 = @list.sprints['s1']
9
- @s2 = @list.sprints['s2']
10
- end
11
-
12
- test "Sprints" do
13
- assert_equal 2, @list.sprints.size
14
- assert_equal 'Sprint one', @s1.name
15
- assert_equal 'Sprint two', @s2.name
16
- end
17
-
18
- test "Sprint model attributes" do
19
- sprint = @list.sprints['s1']
20
- assert_equal 'Sprint one', sprint.name
21
- assert_equal @list, sprint.list
22
- end
23
-
24
- test "Tasks should be assigned to sprints" do
25
- assert_equal @s1, @list['Version 1']['Account']['Login'].sprint
26
- end
27
-
28
- test "Task#contains_sprint?" do
29
- assert @list.contains_sprint?(@s1)
30
- assert @list.contains_sprint?(@s2)
31
- end
32
-
33
- test "Task#contains_sprint? part 2" do
34
- task = @list['Version 1']['Account']['Login']
35
- assert task.contains_sprint?(@s1)
36
- assert ! task.contains_sprint?(@s2)
37
- end
38
-
39
- test "Task#filter_by_sprint" do
40
- list = @list.filter_by_sprint(@s1)
41
- assert ! list['Version 1']['Account']['Login'].nil?
42
- assert list['Version 1']['Account']['Signup'].nil?
43
- end
4
+ setup do
5
+ @list = TPS::TaskList.new yaml: f('sprints.yml')
6
+ @milestone = @list.tasks.first
7
+ @s1 = @list.sprints['s1']
8
+ @s2 = @list.sprints['s2']
9
+ end
44
10
 
45
- test "Sub-tasks of a sprint task" do
46
- list = @list.filter_by_sprint(@s1)
47
- task = list['Version 1']['Comments']['Creating']
48
- assert ! task.nil?
49
- end
11
+ test "Sprints" do
12
+ assert_equal 2, @list.sprints.size
13
+ assert_equal 'Sprint one', @s1.name
14
+ assert_equal 'Sprint two', @s2.name
15
+ end
50
16
 
51
- test "Sprint#index" do
52
- assert_equal 0, @list.sprints['s1'].index
53
- assert_equal 1, @list.sprints['s2'].index
54
- end
17
+ test "Sprint model attributes" do
18
+ sprint = @list.sprints['s1']
19
+ assert_equal 'Sprint one', sprint.name
20
+ assert_equal @list, sprint.list
21
+ end
55
22
 
56
- test "Sprint#points" do
57
- assert_equal 5, @s1.points
58
- end
23
+ test "Tasks should be assigned to sprints" do
24
+ assert @list['Version 1']['Account']['Login'].sprints.include?(@s1)
25
+ end
59
26
 
60
- test "Sprint#points_done" do
61
- assert_equal 3, @s1.points_done
62
- end
27
+ test "Task#contains_sprint?" do
28
+ assert @list.contains_sprint?(@s1)
29
+ assert @list.contains_sprint?(@s2)
63
30
  end
64
31
 
65
- context "Sprint points" do
66
- setup do
67
- @list = TPS::TaskList.new yaml: f('sprint_points.yml')
68
- @milestone = @list.tasks.first
69
- @s = %w[_ s1 s2 s3 s4 s5].map { |id| @list.sprints[id] }
70
- end
32
+ test "Task#contains_sprint? part 2" do
33
+ task = @list['Version 1']['Account']['Login']
34
+ assert task.contains_sprint?(@s1)
35
+ assert ! task.contains_sprint?(@s2)
36
+ end
71
37
 
72
- test "S1 points" do
73
- assert_equal 1.0, @s[1].points
74
- end
38
+ test "Task#filter_by_sprint" do
39
+ list = @list.filter_by_sprint(@s1)
40
+ assert ! list['Version 1']['Account']['Login'].nil?
41
+ assert list['Version 1']['Account']['Signup'].nil?
42
+ end
75
43
 
76
- test "S2 points" do
77
- assert_equal 3.0, @s[2].points
78
- end
44
+ test "Sub-tasks of a sprint task" do
45
+ list = @list.filter_by_sprint(@s1)
46
+ task = list['Version 1']['Comments']['Creating']
47
+ assert ! task.nil?
48
+ end
79
49
 
80
- test "S3 points" do
81
- assert_equal 0.0, @s[3].points
82
- end
50
+ test "Sprint#index" do
51
+ assert_equal 0, @list.sprints['s1'].index
52
+ assert_equal 1, @list.sprints['s2'].index
53
+ end
83
54
 
84
- test "S4 points" do
85
- assert_equal 2.5, @s[4].points
86
- end
55
+ test "Sprint#points" do
56
+ assert_equal 5, @s1.points
57
+ end
87
58
 
88
- test "S5 points" do
89
- assert_equal 1.0, @s[5].points
90
- end
59
+ test "Sprint#points_done" do
60
+ assert_equal 3, @s1.points_done
91
61
  end
92
62
  end
data/test/tps_test.rb CHANGED
@@ -71,6 +71,12 @@ class MyTest < UnitTest
71
71
  assert @milestone.milestone?
72
72
  end
73
73
 
74
+ test "Not milestone" do
75
+ @milestone.tasks.each do |t|
76
+ assert ! t.milestone?
77
+ end
78
+ end
79
+
74
80
  test "HTML works" do
75
81
  assert @list.to_html
76
82
  end
@@ -79,6 +85,23 @@ class MyTest < UnitTest
79
85
  assert_equal @milestone, @list['Milestone 1']
80
86
  end
81
87
 
88
+ context "Task#find" do
89
+ test "self name" do
90
+ end
91
+
92
+ test "descendant" do
93
+ assert_equal @list['Milestone 1'], @list.find('Milestone 1')
94
+ end
95
+
96
+ test "Grand-child" do
97
+ assert_equal @list.tasks[0].tasks[1], @list.find('User login')
98
+ end
99
+
100
+ test "non-existent" do
101
+ assert_equal nil, @list.find("X")
102
+ end
103
+ end
104
+
82
105
  test "Task#breadcrumbs" do
83
106
  crumbs = @list['Milestone 1']['User login']['Signup'].breadcrumbs
84
107
  expected = [
metadata CHANGED
@@ -1,48 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tps_reporter
3
3
  version: !ruby/object:Gem::Version
4
- prerelease:
5
- version: 0.2.2
4
+ version: 0.3.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Rico Sta. Cruz
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2012-12-23 00:00:00.000000000 Z
11
+ date: 2013-06-12 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
- version_requirements: !ruby/object:Gem::Requirement
14
+ name: tilt
15
+ requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ! '>='
17
+ - - '>='
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
- none: false
21
- name: tilt
22
20
  type: :runtime
23
21
  prerelease: false
24
- requirement: !ruby/object:Gem::Requirement
22
+ version_requirements: !ruby/object:Gem::Requirement
25
23
  requirements:
26
- - - ! '>='
24
+ - - '>='
27
25
  - !ruby/object:Gem::Version
28
26
  version: '0'
29
- none: false
30
27
  - !ruby/object:Gem::Dependency
31
- version_requirements: !ruby/object:Gem::Requirement
28
+ name: contest
29
+ requirement: !ruby/object:Gem::Requirement
32
30
  requirements:
33
- - - ! '>='
31
+ - - '>='
34
32
  - !ruby/object:Gem::Version
35
33
  version: '0'
36
- none: false
37
- name: contest
38
34
  type: :development
39
35
  prerelease: false
40
- requirement: !ruby/object:Gem::Requirement
36
+ version_requirements: !ruby/object:Gem::Requirement
41
37
  requirements:
42
- - - ! '>='
38
+ - - '>='
43
39
  - !ruby/object:Gem::Version
44
40
  version: '0'
45
- none: false
46
41
  description: A YAML-powered, simple command-line task report builder.
47
42
  email:
48
43
  - rico@sinefunc.com
@@ -54,47 +49,55 @@ files:
54
49
  - .gitignore
55
50
  - GUIDE.md
56
51
  - HISTORY.md
52
+ - Notes.md
57
53
  - README.md
58
54
  - Rakefile
59
55
  - bin/tps
60
56
  - data/index.haml
61
57
  - data/sample.yml
62
58
  - lib/tps.rb
59
+ - lib/tps/bar_formatter.rb
63
60
  - lib/tps/cli_reporter.rb
64
61
  - lib/tps/importer.rb
65
62
  - lib/tps/sprint.rb
66
63
  - lib/tps/task.rb
67
64
  - lib/tps/task_list.rb
68
65
  - lib/tps/version.rb
66
+ - test/bar_test.rb
69
67
  - test/fixtures/hello.yml
68
+ - test/fixtures/markers.yml
69
+ - test/fixtures/multi_sprints.yml
70
70
  - test/fixtures/sprint_points.yml
71
71
  - test/fixtures/sprints.yml
72
+ - test/html_test.rb
73
+ - test/multi_sprints_test.rb
74
+ - test/sprint_points_test.rb
72
75
  - test/sprint_test.rb
73
76
  - test/test_helper.rb
74
77
  - test/tps_test.rb
75
78
  - tps_reporter.gemspec
76
79
  homepage: http://github.com/rstacruz/tps_reporter
77
80
  licenses: []
81
+ metadata: {}
78
82
  post_install_message:
79
83
  rdoc_options: []
80
84
  require_paths:
81
85
  - lib
82
86
  required_ruby_version: !ruby/object:Gem::Requirement
83
87
  requirements:
84
- - - ! '>='
88
+ - - '>='
85
89
  - !ruby/object:Gem::Version
86
90
  version: '0'
87
- none: false
88
91
  required_rubygems_version: !ruby/object:Gem::Requirement
89
92
  requirements:
90
- - - ! '>='
93
+ - - '>='
91
94
  - !ruby/object:Gem::Version
92
95
  version: '0'
93
- none: false
94
96
  requirements: []
95
97
  rubyforge_project:
96
- rubygems_version: 1.8.23
98
+ rubygems_version: 2.0.2
97
99
  signing_key:
98
- specification_version: 3
100
+ specification_version: 4
99
101
  summary: Task progress sheet reporter.
100
102
  test_files: []
103
+ has_rdoc: