trollolo 0.0.3 → 0.0.4

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.
Files changed (64) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -0
  3. data/.travis.yml +5 -1
  4. data/CHANGELOG.md +29 -0
  5. data/Gemfile +7 -2
  6. data/README.md +19 -0
  7. data/bin/trollolo +1 -1
  8. data/lib/array.rb +6 -0
  9. data/lib/backup.rb +67 -0
  10. data/lib/burndown_chart.rb +96 -67
  11. data/lib/burndown_data.rb +62 -123
  12. data/lib/card.rb +74 -30
  13. data/lib/cli.rb +131 -9
  14. data/lib/column.rb +61 -0
  15. data/lib/result.rb +0 -0
  16. data/lib/scrum_board.rb +104 -0
  17. data/lib/settings.rb +9 -4
  18. data/lib/trello_wrapper.rb +62 -0
  19. data/lib/trollolo.rb +10 -7
  20. data/lib/version.rb +1 -1
  21. data/scripts/.gitignore +1 -0
  22. data/scripts/burndowndata.py +113 -0
  23. data/scripts/create_burndown.py +111 -146
  24. data/scripts/graph.py +116 -0
  25. data/scripts/plot.py +131 -0
  26. data/spec/data/board.json +63 -0
  27. data/spec/data/burndown-data.yaml +3 -0
  28. data/spec/data/burndown_dir/burndown-data-01.yaml +1 -1
  29. data/spec/data/burndown_dir/burndown-data-02.yaml +1 -1
  30. data/spec/data/card.json +61 -0
  31. data/spec/data/full-board.json +1626 -0
  32. data/spec/data/lists.json +25 -25
  33. data/spec/data/trollolorc +5 -0
  34. data/spec/{command_line_spec.rb → integration/command_line_spec.rb} +1 -4
  35. data/spec/integration/create_burndown_spec.rb +57 -0
  36. data/spec/integration/integration_spec_helper.rb +10 -0
  37. data/spec/integration/support/aruba_hook.rb +11 -0
  38. data/spec/integration/support/custom_matchers.rb +13 -0
  39. data/spec/{wrapper → integration/wrapper}/credentials_input_wrapper +2 -2
  40. data/spec/{wrapper → integration/wrapper}/empty_config_trollolo_wrapper +2 -2
  41. data/spec/integration/wrapper/trollolo_wrapper +10 -0
  42. data/spec/unit/backup_spec.rb +107 -0
  43. data/spec/unit/burndown_chart_spec.rb +396 -0
  44. data/spec/unit/burndown_data_spec.rb +118 -0
  45. data/spec/unit/card_spec.rb +79 -0
  46. data/spec/unit/cli_spec.rb +38 -0
  47. data/spec/unit/retrieve_data_spec.rb +54 -0
  48. data/spec/unit/scrum_board_spec.rb +18 -0
  49. data/spec/{settings_spec.rb → unit/settings_spec.rb} +1 -1
  50. data/spec/{spec_helper.rb → unit/spec_helper.rb} +4 -12
  51. data/spec/unit/support/test_data_operations.rb +7 -0
  52. data/spec/unit/support/update_webmock_data +17 -0
  53. data/spec/unit/support/webmocks.rb +52 -0
  54. data/spec/unit/trello_wrapper_spec.rb +47 -0
  55. data/trollolo.gemspec +10 -11
  56. metadata +54 -37
  57. data/lib/trello.rb +0 -66
  58. data/spec/burndown_chart_spec.rb +0 -307
  59. data/spec/burndown_data_spec.rb +0 -125
  60. data/spec/card_spec.rb +0 -15
  61. data/spec/cli_spec.rb +0 -18
  62. data/spec/data/cards.json +0 -1002
  63. data/spec/trello_spec.rb +0 -32
  64. data/spec/wrapper/trollolo_wrapper +0 -11
@@ -1,50 +1,50 @@
1
1
  [
2
2
  {
3
- "pos": 16384,
4
- "subscribed": false,
3
+ "id": "53186e8391ef8671265eba9e",
5
4
  "name": "Sprint Backlog",
6
5
  "closed": false,
7
- "id": "53186e8391ef8671265eba9e",
8
- "idBoard": "53186e8391ef8671265eba9d"
6
+ "idBoard": "53186e8391ef8671265eba9d",
7
+ "pos": 16384,
8
+ "subscribed": false
9
9
  },
10
10
  {
11
- "pos": 32768,
12
- "subscribed": false,
11
+ "id": "53186e8391ef8671265eba9f",
13
12
  "name": "Doing",
14
13
  "closed": false,
15
- "id": "53186e8391ef8671265eba9f",
16
- "idBoard": "53186e8391ef8671265eba9d"
14
+ "idBoard": "53186e8391ef8671265eba9d",
15
+ "pos": 32768,
16
+ "subscribed": false
17
17
  },
18
18
  {
19
- "pos": 36864,
20
- "subscribed": false,
19
+ "id": "5319bf088cdf9cd82be336b0",
21
20
  "name": "Done Sprint 10",
22
21
  "closed": false,
23
- "id": "5319bf088cdf9cd82be336b0",
24
- "idBoard": "53186e8391ef8671265eba9d"
22
+ "idBoard": "53186e8391ef8671265eba9d",
23
+ "pos": 36864,
24
+ "subscribed": false
25
25
  },
26
26
  {
27
- "pos": 40960,
28
- "subscribed": false,
27
+ "id": "5319bf045c6ef0092c55331e",
29
28
  "name": "Done Sprint 9",
30
29
  "closed": false,
31
- "id": "5319bf045c6ef0092c55331e",
32
- "idBoard": "53186e8391ef8671265eba9d"
30
+ "idBoard": "53186e8391ef8671265eba9d",
31
+ "pos": 40960,
32
+ "subscribed": false
33
33
  },
34
34
  {
35
- "pos": 49152,
36
- "subscribed": false,
35
+ "id": "53186e8391ef8671265ebaa0",
37
36
  "name": "Done Sprint 8",
38
37
  "closed": false,
39
- "id": "53186e8391ef8671265ebaa0",
40
- "idBoard": "53186e8391ef8671265eba9d"
38
+ "idBoard": "53186e8391ef8671265eba9d",
39
+ "pos": 49152,
40
+ "subscribed": false
41
41
  },
42
42
  {
43
- "pos": 114688,
44
- "subscribed": false,
43
+ "id": "5319bc0aa338308d42f108d6",
45
44
  "name": "Legend",
46
45
  "closed": false,
47
- "id": "5319bc0aa338308d42f108d6",
48
- "idBoard": "53186e8391ef8671265eba9d"
46
+ "idBoard": "53186e8391ef8671265eba9d",
47
+ "pos": 114688,
48
+ "subscribed": false
49
49
  }
50
- ]
50
+ ]
@@ -1,2 +1,7 @@
1
1
  developer_public_key: mykey
2
2
  member_token: mytoken
3
+ not_done_columns:
4
+ - Blocked
5
+ - Doing
6
+ - In review
7
+ - Sprint Backlog
@@ -1,8 +1,5 @@
1
- require_relative 'spec_helper'
1
+ require_relative 'integration_spec_helper'
2
2
 
3
- require "aruba/api"
4
-
5
- include Aruba::Api
6
3
  include GivenFilesystemSpecHelpers
7
4
 
8
5
  def trollolo_cmd
@@ -0,0 +1,57 @@
1
+ require_relative "integration_spec_helper"
2
+
3
+ include GivenFilesystemSpecHelpers
4
+
5
+ HELPER_SCRIPT = File.expand_path("../../../scripts/create_burndown.py", __FILE__)
6
+
7
+ describe "create_burndown.py" do
8
+ use_given_filesystem(keep_files: true)
9
+
10
+ it "creates burndown chart for sprint 23" do
11
+ @working_dir = given_directory do
12
+ given_file("burndown-data-23.yaml", from: "create_burndown_helper/burndown-data-23.yaml")
13
+ end
14
+
15
+ cmd = "#{HELPER_SCRIPT} 23 --output=#{@working_dir} --no-head"
16
+ run(cmd)
17
+ assert_exit_status(0)
18
+ expect(File.join(@working_dir, "burndown-23.png")).
19
+ to be_same_image_as("create_burndown_helper/burndown-23.png")
20
+ end
21
+
22
+ it "creates burndown chart for sprint 31" do
23
+ @working_dir = given_directory do
24
+ given_file("burndown-data-31.yaml", from: "create_burndown_helper/burndown-data-31.yaml")
25
+ end
26
+
27
+ cmd = "#{HELPER_SCRIPT} 31 --output=#{@working_dir} --no-head"
28
+ run(cmd)
29
+ assert_exit_status(0)
30
+ expect(File.join(@working_dir, "burndown-31.png")).
31
+ to be_same_image_as("create_burndown_helper/burndown-31.png")
32
+ end
33
+
34
+ it "creates burndown chart for sprint 35" do
35
+ @working_dir = given_directory do
36
+ given_file("burndown-data-35.yaml", from: "create_burndown_helper/burndown-data-35.yaml")
37
+ end
38
+
39
+ cmd = "#{HELPER_SCRIPT} 35 --output=#{@working_dir} --no-head"
40
+ run(cmd)
41
+ assert_exit_status(0)
42
+ expect(File.join(@working_dir, "burndown-35.png")).
43
+ to be_same_image_as("create_burndown_helper/burndown-35.png")
44
+ end
45
+
46
+ it "creates burndown chart for sprint 8" do
47
+ @working_dir = given_directory do
48
+ given_file("burndown-data-08.yaml", from: "create_burndown_helper/burndown-data-08.yaml")
49
+ end
50
+
51
+ cmd = "#{HELPER_SCRIPT} 08 --output=#{@working_dir} --no-tasks --with-fast-lane --no-head"
52
+ run(cmd)
53
+ assert_exit_status(0)
54
+ expect(File.join(@working_dir, "burndown-08.png")).
55
+ to be_same_image_as("create_burndown_helper/burndown-08.png")
56
+ end
57
+ end
@@ -0,0 +1,10 @@
1
+ require_relative '../../lib/trollolo'
2
+ require 'given_filesystem/spec_helpers'
3
+
4
+ bin_path = File.expand_path( "../../../bin/", __FILE__ )
5
+
6
+ if ENV['PATH'] !~ /#{bin_path}/
7
+ ENV['PATH'] = bin_path + File::PATH_SEPARATOR + ENV['PATH']
8
+ end
9
+
10
+ Dir.glob(::File.expand_path('../support/*.rb', __FILE__)).each { |f| require_relative f }
@@ -0,0 +1,11 @@
1
+ require 'aruba/api'
2
+ require 'aruba/reporting'
3
+
4
+ RSpec.configure do |config|
5
+ config.include Aruba::Api
6
+
7
+ config.before(:each) do
8
+ restore_env
9
+ clean_current_dir
10
+ end
11
+ end
@@ -0,0 +1,13 @@
1
+ RSpec::Matchers.define :be_same_image_as do |expected|
2
+ match do |actual|
3
+ expected_path = File.expand_path('../../../data/' + expected, __FILE__)
4
+ expected_file = File.binread(expected_path)
5
+ actual_file = File.binread(actual)
6
+
7
+ expected_file == actual_file
8
+ end
9
+
10
+ description do
11
+ "be the same image as \"#{expected}\""
12
+ end
13
+ end
@@ -1,10 +1,10 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  require "expect"
4
4
  require "pty"
5
5
 
6
6
  config_path = "/tmp/test-trollolorc-#{rand(100000)}"
7
- bin_path = File.expand_path('../../../bin/trollolo',__FILE__)
7
+ bin_path = File.expand_path('../../../../bin/trollolo',__FILE__)
8
8
 
9
9
  ENV["TROLLOLO_CONFIG_PATH"] = config_path
10
10
 
@@ -1,7 +1,7 @@
1
- #!/usr/bin/ruby
1
+ #!/usr/bin/env ruby
2
2
 
3
3
  config_path = "/tmp/test-trollolorc-#{rand(100000)}"
4
- bin_path = File.expand_path('../../../bin/trollolo',__FILE__)
4
+ bin_path = File.expand_path('../../../../bin/trollolo',__FILE__)
5
5
 
6
6
  ENV["TROLLOLO_CONFIG_PATH"] = config_path
7
7
 
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ test_config_path = File.expand_path('../../../data/trollolorc',__FILE__)
4
+ bin_path = File.expand_path('../../../../bin/trollolo',__FILE__)
5
+
6
+ ENV["TROLLOLO_CONFIG_PATH"] = test_config_path
7
+
8
+ cmd = "#{bin_path} #{ARGV.join(" ")}"
9
+
10
+ exec(cmd)
@@ -0,0 +1,107 @@
1
+ require_relative "spec_helper"
2
+
3
+ include GivenFilesystemSpecHelpers
4
+
5
+ describe Backup do
6
+ it "sets backup directory" do
7
+ backup = Backup.new(dummy_settings)
8
+ expect(backup.directory).to match File.expand_path("~/.trollolo/backup")
9
+ end
10
+
11
+ context "custom backup directory" do
12
+ use_given_filesystem(keep_files: true)
13
+
14
+ before(:each) do
15
+ full_board_mock
16
+ @backup = Backup.new(dummy_settings)
17
+ @directory = given_directory
18
+ @backup.directory = @directory
19
+ end
20
+
21
+ it "backups board" do
22
+ @backup.backup("53186e8391ef8671265eba9d")
23
+ backup_file = File.join(@directory, "53186e8391ef8671265eba9d", "board.json")
24
+ expect(File.exist?(backup_file)).to be true
25
+ expect(File.read(backup_file)).to eq load_test_file("full-board.json").chomp
26
+ end
27
+
28
+ it "lists backups" do
29
+ @backup.backup("53186e8391ef8671265eba9d")
30
+ expect(@backup.list).to eq ["53186e8391ef8671265eba9d"]
31
+ end
32
+
33
+ it "shows backup" do
34
+ output_capturer = StringIO.new
35
+ @backup.backup("53186e8391ef8671265eba9d")
36
+ @backup.show("53186e8391ef8671265eba9d", output: output_capturer )
37
+ expect(output_capturer.string).to eq(<<EOT
38
+ Trollolo Testing Board
39
+ Sprint Backlog
40
+ Sprint 3
41
+ (3) P1: Fill Backlog column
42
+ Tasks
43
+ Add card to fill Backlog column (incomplete)
44
+ Add card to read data from Trollolo (incomplete)
45
+ Add card to save read data as reference data (incomplete)
46
+ Add card under the waterline (incomplete)
47
+ (5) P4: Read data from Trollolo
48
+ Tasks
49
+ Add option to Trollolo to provide the board id (incomplete)
50
+ Call command (incomplete)
51
+ (3) P5: Save read data as reference data
52
+ Tasks
53
+ Save test data (incomplete)
54
+ Make tests work (incomplete)
55
+ Waterline
56
+ (8) P6: Celebrate testing board
57
+ Tasks
58
+ Party (incomplete)
59
+ Doing
60
+ (2) P2: Fill Doing column
61
+ Tasks
62
+ Add task to add task to Fill Doing column card (incomplete)
63
+ Create card to Fill Doing column (complete)
64
+ Feedback
65
+ Ask user who requested the feature (complete)
66
+ Ask product manager (incomplete)
67
+ Done Sprint 10
68
+ Burndown chart
69
+ Sprint 10
70
+ (3) P3: Fill Done columns
71
+ Tasks
72
+ Fill Done Sprint 1 (complete)
73
+ Fill Done Sprint 2 (complete)
74
+ Fill Done Sprint 3 (complete)
75
+ Done Sprint 9
76
+ Burndown chart
77
+ Sprint 9
78
+ (2) P1: Explain purpose
79
+ (2) P2: Create Scrum columns
80
+ Tasks
81
+ Backlog (complete)
82
+ Doing (complete)
83
+ Multiple Done Columns (complete)
84
+ Done Sprint 8
85
+ Burndown chart
86
+ Sprint 8
87
+ (1) P1: Create Trello Testing Board
88
+ Tasks
89
+ Create board (complete)
90
+ Name board (complete)
91
+ (5) P2: Add fancy background
92
+ Tasks
93
+ Find image (complete)
94
+ Download image (complete)
95
+ Set image (complete)
96
+ Add attribution (complete)
97
+ (1) P4: Add legend
98
+ Tasks
99
+ Create Legend column (complete)
100
+ Legend
101
+ Purpose
102
+ Background image
103
+ EOT
104
+ )
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,396 @@
1
+ require_relative 'spec_helper'
2
+
3
+ include GivenFilesystemSpecHelpers
4
+
5
+ describe BurndownChart do
6
+
7
+ before(:each) do
8
+ @settings = dummy_settings
9
+ @burndown_data = BurndownData.new(@settings)
10
+ @chart = BurndownChart.new(@settings)
11
+ full_board_mock
12
+ end
13
+
14
+ describe "initializer" do
15
+ it "sets initial meta data" do
16
+ expect(@chart.data["meta"]["sprint"]).to eq 1
17
+ expect(@chart.data["meta"]["total_days"]).to eq 10
18
+ expect(@chart.data["meta"]["weekend_lines"]).to eq [3.5, 8.5]
19
+ end
20
+ end
21
+
22
+ describe "data" do
23
+ use_given_filesystem
24
+
25
+ before(:each) do
26
+ @raw_data = [
27
+ {
28
+ "date" => '2014-04-23',
29
+ "updated_at" => '2014-04-23T10:00:00+01:00',
30
+ "story_points" =>
31
+ {
32
+ "total" => 30,
33
+ "open" => 23
34
+ },
35
+ "tasks" =>
36
+ {
37
+ "total" => 25,
38
+ "open" => 21
39
+ }
40
+ },
41
+ {
42
+ "date" => '2014-04-24',
43
+ "updated_at" => '2014-04-24T19:00:00+01:00',
44
+ "story_points" =>
45
+ {
46
+ "total" => 30,
47
+ "open" => 21
48
+ },
49
+ "tasks" =>
50
+ {
51
+ "total" => 26,
52
+ "open" => 19
53
+ },
54
+ "story_points_extra" =>
55
+ {
56
+ "done" => 3
57
+ },
58
+ "tasks_extra" =>
59
+ {
60
+ "done" => 2
61
+ }
62
+ }
63
+ ]
64
+ end
65
+
66
+ it "creates first data entry" do
67
+ @burndown_data.story_points.open = 16
68
+ @burndown_data.story_points.done = 7
69
+ @burndown_data.tasks.open = 10
70
+ @burndown_data.tasks.done = 11
71
+ @burndown_data.date_time = DateTime.parse("2014-05-30")
72
+
73
+ @chart.add_data(@burndown_data)
74
+
75
+ expect( @chart.data["days"].first["story_points"] ).to eq(
76
+ {
77
+ "total" => 23,
78
+ "open" => 16
79
+ } )
80
+ expect( @chart.data["days"].first["tasks"] ).to eq(
81
+ {
82
+ "total" => 21,
83
+ "open" => 10
84
+ } )
85
+ end
86
+
87
+ it "returns sprint number" do
88
+ expect(@chart.sprint).to eq 1
89
+ end
90
+
91
+ it "adds data" do
92
+ @chart.data["days"] = @raw_data
93
+
94
+ @burndown_data.story_points.open = 16
95
+ @burndown_data.story_points.done = 7
96
+ @burndown_data.tasks.open = 10
97
+ @burndown_data.tasks.done = 11
98
+ @burndown_data.extra_story_points.open = 2
99
+ @burndown_data.extra_story_points.done = 3
100
+ @burndown_data.extra_tasks.open = 5
101
+ @burndown_data.extra_tasks.done = 2
102
+ @burndown_data.date_time = DateTime.parse("2014-05-30")
103
+
104
+ @chart.add_data(@burndown_data)
105
+
106
+ expect( @chart.data["days"].count ).to eq 3
107
+ expect( @chart.data["days"].last["date"] ).to eq ( "2014-05-30" )
108
+ expect( @chart.data["days"].last["story_points"] ).to eq ( {
109
+ "total" => 23,
110
+ "open" => 16
111
+ } )
112
+ expect( @chart.data["days"].last["tasks"] ).to eq ( {
113
+ "total" => 21,
114
+ "open" => 10
115
+ } )
116
+ expect( @chart.data["days"].last["story_points_extra"] ).to eq ( {
117
+ "done" => 3
118
+ } )
119
+ expect( @chart.data["days"].last["tasks_extra"] ).to eq ( {
120
+ "done" => 2
121
+ } )
122
+ end
123
+
124
+ it "replaces data of same day" do
125
+ @chart.data["days"] = @raw_data
126
+
127
+ @burndown_data.story_points.open = 16
128
+ @burndown_data.story_points.done = 7
129
+ @burndown_data.tasks.open = 10
130
+ @burndown_data.tasks.done = 11
131
+ @burndown_data.date_time = DateTime.parse("2014-05-30")
132
+
133
+ @chart.add_data(@burndown_data)
134
+
135
+ expect( @chart.data["days"].count ).to eq 3
136
+ expect( @chart.data["days"].last["story_points"] ).to eq ( {
137
+ "total" => 23,
138
+ "open" => 16
139
+ } )
140
+
141
+ @burndown_data.story_points.done = 8
142
+ @chart.add_data(@burndown_data)
143
+
144
+ expect( @chart.data["days"].count ).to eq 3
145
+ expect( @chart.data["days"].last["story_points"] ).to eq ( {
146
+ "total" => 24,
147
+ "open" => 16
148
+ } )
149
+ end
150
+
151
+ describe "#read_data" do
152
+ it "reads data" do
153
+ @chart.read_data given_file('burndown-data.yaml')
154
+
155
+ expect(@chart.data["days"]).to eq @raw_data
156
+ end
157
+
158
+ it "reads not done columns" do
159
+ @chart.read_data given_file('burndown-data.yaml', from: 'burndown-data-with-config.yaml')
160
+ expect(@settings.not_done_columns).to eq ["Sprint Backlog", "Doing", "QA"]
161
+ end
162
+ end
163
+
164
+ describe "#write_data" do
165
+ it "writes object to disk" do
166
+ @chart.sprint = 2
167
+ @chart.data["meta"]["total_days"] = 9
168
+ @chart.data["meta"]["weekend_lines"] = [3.5, 7.5]
169
+ @chart.data["meta"]["board_id"] = "myboardid"
170
+ @chart.data["days"] = @raw_data
171
+
172
+ write_path = given_dummy_file
173
+ @chart.write_data(write_path)
174
+ expect(File.read(write_path)). to eq load_test_file('burndown-data.yaml')
175
+ end
176
+
177
+ it "writes all data which was read" do
178
+ read_path = given_file('burndown-data.yaml')
179
+ @chart.read_data(read_path)
180
+
181
+ write_path = given_dummy_file
182
+ @chart.write_data(write_path)
183
+
184
+ expect(File.read(write_path)).to eq File.read(read_path)
185
+ end
186
+
187
+ it "doesn't write extra entries with 0 values" do
188
+ raw_data = [
189
+ {
190
+ "date" => '2014-04-24',
191
+ "story_points" =>
192
+ {
193
+ "total" => 30,
194
+ "open" => 21
195
+ },
196
+ "tasks" =>
197
+ {
198
+ "total" => 26,
199
+ "open" => 19
200
+ },
201
+ "story_points_extra" =>
202
+ {
203
+ "done" => 0
204
+ },
205
+ "tasks_extra" =>
206
+ {
207
+ "done" => 0
208
+ }
209
+ }
210
+ ]
211
+ @chart.data["days"] = raw_data
212
+ @chart.data["meta"]["board_id"] = "1234"
213
+
214
+ write_path = given_dummy_file
215
+ @chart.write_data(write_path)
216
+
217
+ expected_file_content = <<EOT
218
+ ---
219
+ meta:
220
+ board_id: '1234'
221
+ sprint: 1
222
+ total_days: 10
223
+ weekend_lines:
224
+ - 3.5
225
+ - 8.5
226
+ days:
227
+ - date: '2014-04-24'
228
+ story_points:
229
+ total: 30
230
+ open: 21
231
+ tasks:
232
+ total: 26
233
+ open: 19
234
+ EOT
235
+ expect(File.read(write_path)).to eq expected_file_content
236
+ end
237
+ end
238
+
239
+ end
240
+
241
+ describe "commands" do
242
+ use_given_filesystem(keep_files: true)
243
+
244
+ describe "setup" do
245
+ it "initializes new chart" do
246
+ path = given_directory
247
+ @chart.setup(path,"53186e8391ef8671265eba9d")
248
+
249
+ expect(File.exist?(File.join(path,"burndown-data-01.yaml"))).to be true
250
+
251
+ chart = BurndownChart.new(@settings)
252
+ chart.read_data(File.join(path,"burndown-data-01.yaml"))
253
+
254
+ expect(chart.board_id).to eq "53186e8391ef8671265eba9d"
255
+ end
256
+ end
257
+
258
+ describe "last_sprint" do
259
+ it "gets the last sprint based on the burndown files" do
260
+ path = given_directory_from_data("burndown_dir")
261
+ expect(@chart.last_sprint(path)).to eq(2)
262
+ end
263
+ end
264
+
265
+ describe "load_last_sprint" do
266
+ let(:path) { given_directory_from_data("burndown_dir") }
267
+ it "loads the burndown form the 2nd sprint into data" do
268
+ @chart.load_last_sprint(path)
269
+ expect(@chart.data).to eq({"meta"=>
270
+ {"board_id"=>"53186e8391ef8671265eba9d",
271
+ "sprint"=>2,
272
+ "total_days"=>9,
273
+ "weekend_lines"=>[3.5, 7.5]},
274
+ "days"=>[]})
275
+ end
276
+
277
+ it "returns the path of the last sprint" do
278
+ expect(@chart.load_last_sprint(path)).to eq(File.join(path,"burndown-data-02.yaml"))
279
+ end
280
+ end
281
+
282
+ describe "update" do
283
+ let(:path) { given_directory_from_data("burndown_dir") }
284
+ let(:options) { {'output' => path} }
285
+ let(:before) { BurndownChart.new(@settings) }
286
+ let(:after) { BurndownChart.new(@settings) }
287
+
288
+ it "updates chart with latest data" do
289
+ updated_at = "2015-01-12T13:57:16+01:00"
290
+ expected_date_time = DateTime.parse(updated_at)
291
+ allow(DateTime).to receive(:now).and_return(expected_date_time)
292
+
293
+ before.read_data(File.join(path,'burndown-data-02.yaml'))
294
+ @chart.update(options)
295
+ after.read_data(File.join(path,'burndown-data-02.yaml'))
296
+ expect(after.days.size).to eq before.days.size + 1
297
+
298
+ expect(after.days.last["date"]).to eq "2015-01-12"
299
+ expect(after.days.last["updated_at"]).to eq updated_at
300
+ end
301
+
302
+ it "overwrites data on same date" do
303
+ before.read_data(File.join(path,'burndown-data-02.yaml'))
304
+ @chart.update(options)
305
+ @chart.update(options)
306
+ after.read_data(File.join(path,'burndown-data-02.yaml'))
307
+ expect(after.days.size).to eq before.days.size + 1
308
+ end
309
+ end
310
+
311
+ describe "create_next_sprint" do
312
+ it "create new sprint file" do
313
+ path = given_directory_from_data("burndown_dir")
314
+ chart = BurndownChart.new(@settings)
315
+ chart.create_next_sprint(path)
316
+
317
+ next_sprint_file = File.join(path, "burndown-data-03.yaml")
318
+ expect(File.exist?(next_sprint_file)).to be true
319
+
320
+ expected_file_content = <<EOT
321
+ ---
322
+ meta:
323
+ board_id: 53186e8391ef8671265eba9d
324
+ sprint: 3
325
+ total_days: 9
326
+ weekend_lines:
327
+ - 3.5
328
+ - 7.5
329
+ days: []
330
+ EOT
331
+ expect(File.read(next_sprint_file)).to eq expected_file_content
332
+ end
333
+ end
334
+ end
335
+
336
+ describe "reads meta data from the board" do
337
+
338
+ use_given_filesystem
339
+
340
+ it "merges meta data from board if present" do
341
+ chart = BurndownChart.new(@settings)
342
+ chart.read_data(given_file("burndown-data-10.yaml"))
343
+
344
+ expect(chart.data["meta"]["weekend_lines"]).to eq([3.5, 8.5])
345
+
346
+ burndown = BurndownData.new(@settings)
347
+ burndown.board_id = "53186e8391ef8671265eba9d"
348
+ burndown.fetch
349
+
350
+ chart.merge_meta_data_from_board(burndown)
351
+
352
+ expect(chart.data["meta"]["weekend_lines"]).to eq([1.5, 6.5, 11.5, 16.5])
353
+ end
354
+ end
355
+
356
+ describe '.plot' do
357
+
358
+ it 'sends joined parsed options to python script' do
359
+ allow(described_class).to receive(:process_options).and_return(%w{ --test 1 --no-blah })
360
+ allow(described_class).to receive(:plot_helper).and_return('mescript')
361
+ expect(described_class).to receive(:system).with('python mescript 42 --test 1 --no-blah')
362
+ described_class.plot(42, {foo: 1, bar: 2})
363
+ end
364
+
365
+ end
366
+
367
+ describe '.plot_helper' do
368
+
369
+ it 'expands path to burndown generator' do
370
+ expect(described_class.plot_helper).to include('scripts/create_burndown.py')
371
+ end
372
+
373
+ end
374
+
375
+ describe '.process_options' do
376
+
377
+ it 'builds an array of switches for burndown chart based on input hash' do
378
+ test_hash = { 'no-tasks' => true }
379
+ expect(described_class.send(:process_options, test_hash)).to eq %w{ --no-tasks }
380
+ test_hash = { 'with-fast-lane' => true }
381
+ expect(described_class.send(:process_options, test_hash)).to eq %w{ --with-fast-lane }
382
+ test_hash = { 'output' => 'fanagoro' }
383
+ expect(described_class.send(:process_options, test_hash)).to eq [ '--output fanagoro' ]
384
+ test_hash = {}
385
+ expect(described_class.send(:process_options, test_hash)).to eq [ ]
386
+ test_hash = {
387
+ 'no-tasks' => true,
388
+ 'with-fast-lane' => true,
389
+ 'output' => 'fanagoro',
390
+ 'verbose' => true
391
+ }
392
+ expect(described_class.send(:process_options, test_hash)).to eq ['--no-tasks', '--with-fast-lane', '--output fanagoro', '--verbose']
393
+ end
394
+
395
+ end
396
+ end