achoo 0.4.2 → 0.5

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 (40) hide show
  1. data/CHANGES +13 -0
  2. data/README.rdoc +26 -22
  3. data/lib/achoo/achievo/hour_administration_form.rb +2 -3
  4. data/lib/achoo/achievo/hour_registration_form.rb +12 -15
  5. data/lib/achoo/achievo/hour_registration_form_ranged.rb +5 -2
  6. data/lib/achoo/achievo/lock_month_form.rb +1 -5
  7. data/lib/achoo/achievo/login_form.rb +3 -3
  8. data/lib/achoo/app.rb +27 -28
  9. data/lib/achoo/awake.rb +1 -1
  10. data/lib/achoo/extensions.rb +4 -0
  11. data/lib/achoo/ical.rb +6 -2
  12. data/lib/achoo/plugin/awake.rb +23 -0
  13. data/lib/achoo/plugin/ical.rb +47 -0
  14. data/lib/achoo/plugin/vcs.rb +26 -0
  15. data/lib/achoo/plugin_base.rb +6 -0
  16. data/lib/achoo/rc_loader.rb +9 -0
  17. data/lib/achoo/temporal/timespan.rb +3 -3
  18. data/lib/achoo/term.rb +7 -3
  19. data/lib/achoo/term/table.rb +5 -6
  20. data/lib/achoo/ui/commands.rb +12 -12
  21. data/lib/achoo/ui/date_chooser.rb +1 -1
  22. data/lib/achoo/ui/exception_handling.rb +1 -1
  23. data/lib/achoo/ui/register_hours.rb +50 -50
  24. data/lib/achoo/vcs/git.rb +5 -3
  25. data/test/acceptance/test_flexi_time.rb +41 -0
  26. data/test/acceptance/test_lock_month.rb +39 -0
  27. data/test/acceptance/test_register_hours.rb +161 -0
  28. data/test/lib/achievo_mock.rb +76 -0
  29. data/test/lib/achoo_runner.rb +54 -0
  30. data/test/lib/test_helpers.rb +43 -0
  31. data/test/unit/test_achievo_date_field.rb +34 -0
  32. data/test/unit/test_awake.rb +98 -0
  33. data/test/unit/test_extensions_array.rb +25 -0
  34. data/test/unit/test_system_cstruct.rb +28 -0
  35. data/test/unit/test_system_log_entry.rb +31 -0
  36. data/test/unit/test_term_menu.rb +71 -0
  37. data/test/unit/test_term_table.rb +52 -0
  38. data/test/unit/test_timespan.rb +48 -0
  39. data/test/unit/test_ui_date_chooser.rb +36 -0
  40. metadata +101 -74
@@ -0,0 +1,26 @@
1
+ require 'achoo'
2
+ require 'achoo/vcs'
3
+ require 'achoo/ui'
4
+ require 'plugman/plugin_base'
5
+
6
+ module Achoo
7
+ class Plugin
8
+ class VCS < Plugman::PluginBase
9
+
10
+ include UI::ExceptionHandling
11
+
12
+ def state_ok?; RC.has_key?(:vcs_dirs); end
13
+
14
+ def before_register_hour_remark(date)
15
+ puts '-' * 80
16
+ puts "VCS logs for #{date}:"
17
+ begin
18
+ Achoo::VCS.print_logs_for(date, RC[:vcs_dirs])
19
+ rescue Exception => e
20
+ puts handle_exception("Failed to retrieve VCS logs.", e)
21
+ end
22
+ end
23
+
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,6 @@
1
+ require 'plugman/plugin_base'
2
+
3
+ module Achoo
4
+ class PluginBase < Plugman::PluginBase
5
+ end
6
+ end
@@ -49,6 +49,15 @@ module Achoo
49
49
  RC[key] = []
50
50
  end
51
51
  end
52
+
53
+ if RC.has_key?(:ical)
54
+ RC[:ical].each do |cal|
55
+ if cal.has_key?(:host)
56
+ puts Term.warn "You are using the old configuration format for ical. See the README for information on the new format"
57
+ return
58
+ end
59
+ end
60
+ end
52
61
  end
53
62
 
54
63
  end
@@ -18,14 +18,14 @@ module Achoo
18
18
  def contains?(timeish_or_timespan)
19
19
  if timeish_or_timespan.is_a? Timespan
20
20
  time = timeish_or_timespan
21
- include?(time.first) && include?(time.last)
21
+ cover?(time.first) && cover?(time.last)
22
22
  else
23
- include?(to_time(timeish_or_timespan))
23
+ cover?(to_time(timeish_or_timespan))
24
24
  end
25
25
  end
26
26
 
27
27
  def overlaps?(timespan)
28
- include?(timespan.first) || include?(timespan.last) ||
28
+ cover?(timespan.first) || cover?(timespan.last) ||
29
29
  timespan.contains?(self)
30
30
  end
31
31
 
data/lib/achoo/term.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  require 'achoo'
4
+ require 'readline'
4
5
 
5
6
  module Achoo
6
7
  class Term
@@ -20,6 +21,11 @@ module Achoo
20
21
  def self.warn(text); effect(YELLOW, text); end
21
22
  def self.fatal(text); effect(RED, text); end
22
23
 
24
+ def self.clearscreen
25
+ print "\e[2J\e[H"
26
+ $stdout.flush
27
+ end
28
+
23
29
  def self.password
24
30
  `stty -echo`
25
31
  pas = ask('Password')
@@ -30,9 +36,7 @@ module Achoo
30
36
  def self.ask(question='')
31
37
  answer = nil
32
38
  loop do
33
- print bold("#{question}> ")
34
- $stdout.flush
35
- answer = gets
39
+ answer = Readline.readline(bold("#{question}> "), true)
36
40
 
37
41
  # Answer is nil if user hits C-d on an empty input
38
42
  if answer.nil?
@@ -65,13 +65,12 @@ module Achoo
65
65
  end
66
66
 
67
67
  def calculate_table_cell_widths
68
- lengths = []
69
- @headers.each_with_index do |h, i|
70
- lengths[i] = h.length
71
- end
72
- @data_rows.each do |r|
68
+ rows = [@headers] + @data_rows
69
+ rows += [@summaries] unless @summaries.nil?
70
+ lengths = Array.new(@headers.length, 0)
71
+ rows.each do |r|
73
72
  r.each_with_index do |d, i|
74
- lengths[i] = [d.length, lengths[i]].max
73
+ lengths[i] = [d.scan(/./mu).length, lengths[i]].max # FIX scan is a 1.8 hack
75
74
  end
76
75
  end
77
76
  lengths
@@ -9,30 +9,30 @@ module Achoo
9
9
  include DateChoosers
10
10
  include Common
11
11
 
12
- def show_registered_hours_for_day(agent)
12
+ def show_registered_hours_for_day
13
13
  date = date_chooser
14
- form = Achievo::HourAdministrationForm.new(agent)
14
+ form = Achievo::HourAdministrationForm.new
15
15
  form.show_registered_hours_for_day(date)
16
16
  end
17
17
 
18
- def show_registered_hours_for_week(agent)
18
+ def show_registered_hours_for_week
19
19
  date = date_chooser
20
- form = Achievo::HourAdministrationForm.new(agent)
20
+ form = Achievo::HourAdministrationForm.new
21
21
  form.show_registered_hours_for_week(date)
22
22
  end
23
23
 
24
24
 
25
- def show_flexi_time(agent)
25
+ def show_flexi_time
26
26
  date = date_chooser
27
- form = Achievo::HourAdministrationForm.new(agent)
27
+ form = Achievo::HourAdministrationForm.new
28
28
  balance = form.flexi_time(date)
29
29
  puts "Flexi time balance: #{Term::underline(balance)}"
30
30
  end
31
31
 
32
32
 
33
- def lock_month(agent)
33
+ def lock_month
34
34
  month = month_chooser
35
- form = Achievo::LockMonthForm.new(agent)
35
+ form = Achievo::LockMonthForm.new
36
36
  form.lock_month(month)
37
37
  form.print_values
38
38
  if confirm
@@ -43,20 +43,20 @@ module Achoo
43
43
  end
44
44
 
45
45
 
46
- def show_holiday_report(agent)
47
- page = agent.get(RC[:holiday_report_url])
46
+ def show_holiday_report
47
+ page = AGENT.get(RC[:holiday_report_url])
48
48
  page.body.match(/<b>(\d+,\d+)<\/b>/)
49
49
  puts "Balance: #{Term::underline($1)}"
50
50
  end
51
51
 
52
52
 
53
- def view_report(agent)
53
+ def view_report
54
54
  choices = RC[:reports].keys
55
55
  answer = Term.choose('Report', choices)
56
56
  key = choices[answer.to_i - 1]
57
57
 
58
58
  puts "Fetching data ..."
59
- page = agent.get(RC[:url] + RC[:reports][key])
59
+ page = AGENT.get(RC[:url] + RC[:reports][key])
60
60
 
61
61
  table = Achievo::Table.new(page.search('#rl_1 tr'))
62
62
  table.select_columns do |c|
@@ -67,7 +67,7 @@ module Achoo
67
67
  puts "Accepted formats:"
68
68
  puts date_format_help_string
69
69
  puts
70
- system 'cal -3m'
70
+ system 'cal -3'
71
71
  end
72
72
 
73
73
  def date_format_help_string
@@ -14,7 +14,7 @@ module Achoo
14
14
  end
15
15
 
16
16
  def get_exception_reason(e)
17
- "\nReason: \n\t" + e.message.gsub("\n", "\n\t") + "\n---\n\t" + e.backtrace.join("\n\t")
17
+ "\nType:\t" + e.class.to_s + "\nReason: \n\t" + e.message.gsub("\n", "\n\t") + "\n---\n\t" + e.backtrace.join("\n\t")
18
18
  end
19
19
 
20
20
  end
@@ -1,9 +1,7 @@
1
1
  require 'achoo/achievo'
2
- require 'achoo/awake'
3
- require 'achoo/ical'
4
2
  require 'achoo/term'
5
3
  require 'achoo/ui'
6
- require 'achoo/vcs'
4
+ require 'readline'
7
5
 
8
6
  module Achoo
9
7
  module UI
@@ -12,7 +10,10 @@ module Achoo
12
10
  include DateChoosers
13
11
  include ExceptionHandling
14
12
 
15
- def register_hours(agent)
13
+ def initialize
14
+ end
15
+
16
+ def register_hours
16
17
  date = optionally_ranged_date_chooser
17
18
 
18
19
  puts "Fetching data ..."
@@ -20,14 +21,14 @@ module Achoo
20
21
  Achievo::HourRegistrationFormRanged
21
22
  else
22
23
  Achievo::HourRegistrationForm
23
- end.new(agent)
24
+ end.new
24
25
 
25
26
  form.date = date
26
27
  form.project = project_chooser(form)
27
28
  form.phase = phase_chooser(form)
28
- print_remark_help(date) unless date.class == Array
29
+ PLUGINS.send_before_register_hour_remark(date) unless date.class == Array
29
30
  form.remark = remark_chooser
30
- print_hours_help(date) unless date.class == Array
31
+ PLUGINS.send_before_register_hour_hours(date) unless date.class == Array
31
32
  form.hours = hours_chooser
32
33
 
33
34
  answer = Term.ask("Do you want to change the defaults for worktime period and/or billing percentage? [N/y]").downcase
@@ -43,6 +44,8 @@ module Achoo
43
44
  else
44
45
  puts "Cancelled"
45
46
  end
47
+
48
+ date
46
49
  end
47
50
 
48
51
 
@@ -53,17 +56,6 @@ module Achoo
53
56
  end
54
57
 
55
58
 
56
- def print_hours_help(date)
57
- puts "Awake log:"
58
- begin
59
- awake = Awake.new
60
- awake.at(date)
61
- puts
62
- rescue Exception => e
63
- print handle_exception("Failed to retrieve awake log.", e)
64
- end
65
- end
66
-
67
59
  def hours_chooser
68
60
  answer = Term::ask 'Hours [7:30]'
69
61
  return answer == '' ? '7.5' : answer
@@ -83,25 +75,6 @@ module Achoo
83
75
  true)
84
76
  end
85
77
 
86
- def print_remark_help(date)
87
- puts "VCS logs for #{date}:"
88
- begin
89
- VCS.print_logs_for(date, RC[:vcs_dirs])
90
- rescue Exception => e
91
- puts handle_exception("Failed to retrieve VCS logs.", e)
92
- end
93
- puts '-' * 80
94
- puts "Calendar events for #{date}:"
95
- puts '---'
96
- begin
97
- RC[:ical].each do |config|
98
- ICal.from_http_request(config).print_events(date)
99
- end
100
- rescue Exception => e
101
- puts handle_exception("Failed to retrieve calendar events.", e)
102
- end
103
- end
104
-
105
78
  def remark_chooser
106
79
  Term::ask 'Remark'
107
80
  end
@@ -112,29 +85,56 @@ module Achoo
112
85
  projects = form.recent_projects
113
86
  answer = Term.choose('Project [1]', projects.collect { |p| p[1] },
114
87
  'Other', [''])
115
- case answer
116
- when ''
117
- projects[0][0]
118
- when '0'
119
- return all_projects_chooser(form)
120
- else
121
- return projects[answer.to_i-1][0]
122
- end
88
+ return case answer
89
+ when '0'
90
+ all_projects_chooser(form)
91
+ when ''
92
+ projects[0][0]
93
+ else
94
+ projects[answer.to_i-1][0]
95
+ end
123
96
  end
124
97
 
125
98
 
126
99
 
127
100
  def all_projects_chooser(form)
128
- chooser_helper(form.all_projects,
129
- 'All projects',
130
- 'Project')
101
+ projects = form.all_projects
102
+
103
+ p projects
104
+
105
+ # FIX move readline stuff to the term modules
106
+ original_readline_comp_proc = Readline.completion_proc
107
+ original_readline_comp_append_char = Readline.completion_append_character
108
+ Readline.completion_append_character = ''
109
+ Readline.completion_proc = proc do |s|
110
+ projects.collect {|p| p[1] }.grep(/^#{Regexp.escape(s)}/)
111
+ end
112
+
113
+
114
+ answer = chooser_helper(projects,
115
+ 'All projects',
116
+ 'Project')
117
+
118
+ Readline.completion_proc = original_readline_comp_proc
119
+ Readline.completion_append_character = original_readline_comp_append_char
120
+
121
+ answer
131
122
  end
132
123
 
133
124
  def chooser_helper(options, heading, prompt, empty_allowed=false)
134
- puts heading
135
125
  extra = empty_allowed ? [''] : []
136
- answer = Achoo::Term.choose(prompt, options.collect {|p| p[1] }, nil, [''])
126
+ project_names = options.collect {|p| p[1] }
127
+ if heading == 'All projects'
128
+ # FIX ugly conditional
129
+ extra += project_names
130
+ end
131
+ answer = Achoo::Term.choose(prompt, options.collect {|p| p[1] }, nil, extra)
137
132
  answer = '1' if answer.empty?
133
+ if heading == 'All projects'
134
+ # FIX ugly conditional
135
+ index = project_names.find_index(answer) + 1
136
+ answer = index unless index.nil?
137
+ end
138
138
  options[answer.to_i-1][0]
139
139
  end
140
140
 
data/lib/achoo/vcs/git.rb CHANGED
@@ -13,10 +13,12 @@ module Achoo
13
13
  end
14
14
 
15
15
  def log_for(date)
16
- today = date.strftime('%Y-%m-%d')
17
- tomorrow = date.next.strftime('%Y-%m-%d')
16
+ format = '%Y-%m-%dT00:00:00'
17
+ from = date.strftime(format)
18
+ to = (date+1).strftime(format)
18
19
 
19
- `cd #@dir; git log --author=#{ENV['USER']} --oneline --after=#{today} --before=#{tomorrow} | cut -d ' ' -f 2-`
20
+ cmd = "cd #@dir; git log --author=#{ENV['USER']} --oneline --after=#{from} --before=#{to} | cut -d ' ' -f 2-"
21
+ `#{cmd}`
20
22
  end
21
23
 
22
24
  end
@@ -0,0 +1,41 @@
1
+ require 'test_helpers'
2
+
3
+ class TestFlexiTime < Test::Unit::TestCase
4
+
5
+ include AcceptanceBase
6
+
7
+ def setup
8
+ super
9
+
10
+ hour_administration_html = %q{
11
+ <html>
12
+ <head></head>
13
+ <body>
14
+ <form name="dayview">
15
+ <input type="text" name="viewdate[day]" value="20">
16
+ <input type="text" name="viewdate[month]" value="03">
17
+ <input type="text" name="viewdate[year]" value="2010">
18
+ </form>
19
+
20
+ <p>Flexi time balance: -44:30</p>
21
+
22
+ </body>
23
+ </html>
24
+ }
25
+
26
+ @server.register(:get, '/time_registration', [ 200, nil, hour_administration_html ])
27
+ end
28
+
29
+ def test_flexi_time
30
+ achoo(:verbose => $DEBUG) do
31
+ expect '2. Show flexitime balance'
32
+ expect_main_prompt
33
+ puts '2'
34
+ puts '2010-03-20'
35
+ expect /Flexi time balance:.*-44:30/
36
+ expect_main_prompt
37
+ puts 'q'
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,39 @@
1
+ require 'test_helpers'
2
+
3
+ class TestLockMonth < Test::Unit::TestCase
4
+
5
+ include AcceptanceBase
6
+
7
+ def setup
8
+ super
9
+
10
+ lock_month_html = %q{
11
+ <html>
12
+ <head></head>
13
+ <body>
14
+ <form name="entryform">
15
+ <input type="text" name="period" value="">
16
+ </form>
17
+ </body>
18
+ </html>
19
+ }
20
+
21
+ @server.register(:get, '/lock_months', [ 200, nil, lock_month_html ])
22
+ end
23
+
24
+ def test_lock_month
25
+ achoo(:verbose => $DEBUG) do
26
+ expect '6. Lock month'
27
+ expect_main_prompt
28
+ puts '6'
29
+ expect /Period \(\[\d{6}\] | YYYYMM\)>/
30
+ puts '201003'
31
+ expect 'Month: 201003'
32
+ expect 'Submit? [Y/n]>'
33
+ puts 'n'
34
+ expect 'Cancelled'
35
+ expect_main_prompt
36
+ puts 'q'
37
+ end
38
+ end
39
+ end