trollolo 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
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