timesheet 0.2.8 → 0.3.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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
@@ -0,0 +1,3 @@
1
+ set autolist
2
+ set autoeval
3
+ set autoreload
data/.rvmrc ADDED
@@ -0,0 +1 @@
1
+ rvm 1.9.3@timesheet
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in timesheet.gemspec
4
+ gemspec
data/Rakefile CHANGED
@@ -1,29 +1,11 @@
1
- require 'rubygems'
2
- gem 'hoe', '>= 2.1.0'
3
- require 'hoe'
4
- require 'fileutils'
5
- require './lib/timesheet'
6
-
7
- Hoe::plugin :newgem
8
- Hoe::plugin :gemcutter
9
- # Hoe.plugin :website
10
- # Hoe.plugin :cucumberfeatures
11
-
12
- # Generate all the Rake tasks
13
- # Run 'rake -T' to see list of generated tasks (from gem root directory)
14
- $hoe = Hoe.spec 'timesheet' do
15
- self.developer 'John F. Schank III', 'jschank@mac.com'
16
- self.rubyforge_name = self.name # TODO this is default value
17
- self.extra_deps = [['activesupport', '>= 0'], ['archive-tar-minitar', '>= 0'], ['chronic', '>= 0'], ['hoe', '>= 0'], ['json_pure', '>= 0'], ['newgem', '>= 0'], ['rake', '>= 0'], ['RedCloth', '>= 0'], ['richunits', '>= 0'], ['rspec', '>= 0'], ['rubigen', '>= 0'], ['rubyforge', '>= 0'], ['syntax', '>= 0'], ['transaction-simple', '>= 0']]
18
- # self.extra_deps = [['activesupport','>= 2.0.2']]
19
-
20
- end
21
-
22
- require 'newgem/tasks'
23
- Dir['tasks/**/*.rake'].each { |t| load t }
24
-
25
- # TODO - want other tests/tasks run by default? Add them to the list
26
- # remove_task :default
27
- # task :default => [:spec, :features]
1
+ require "bundler/gem_tasks"
2
+ require 'rake'
3
+ require 'rspec/core/rake_task'
28
4
 
5
+ RSpec::Core::RakeTask.new
29
6
 
7
+ # desc "Run the specs under spec/models"
8
+ # Spec::Rake::SpecTask.new do |t|
9
+ # t.spec_opts = ['--options', "spec/spec.opts"]
10
+ # t.spec_files = FileList['spec/**/*_spec.rb']
11
+ # end
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- $LOAD_PATH.unshift File.dirname(__FILE__) + '/../lib'
3
+ $LOAD_PATH.unshift File.join(File.dirname(__FILE__), '..', 'lib')
4
4
 
5
5
  require 'timesheet'
6
6
 
7
- Timesheet.run(ARGV)
7
+ Timesheet::Timesheet.run(ARGV)
@@ -1,6 +1,3 @@
1
- $:.unshift(File.dirname(__FILE__)) unless
2
- $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
-
4
1
  require 'rubygems'
5
2
  require 'fileutils'
6
3
  require 'richunits'
@@ -14,73 +11,73 @@ require 'timesheet/time_log'
14
11
  require 'timesheet/time_report'
15
12
  require 'timesheet/trollop'
16
13
  require 'timesheet/timesheet_parser'
14
+ require "timesheet/version"
17
15
 
18
- class Timesheet
16
+ module Timesheet
17
+ class Timesheet
19
18
 
20
- VERSION = '0.2.8'
19
+ def self.run(params)
20
+ command_hash = {}
21
+ command_hash = TimesheetParser.parse(params)
21
22
 
22
- def self.run(params)
23
- command_hash = {}
24
- command_hash = TimesheetParser.parse(params)
23
+ raise "Cannot determine location for data. Try timesheet --help for details." unless (ENV["TIMESHEET_DATA_FILE"] || ENV["HOME"])
25
24
 
26
- raise "Cannot determine location for data. Try timesheet --help for details." unless (ENV["TIMESHEET_DATA_FILE"] || ENV["HOME"])
25
+ data_file ||= ENV["TIMESHEET_DATA_FILE"]
26
+ data_file ||= (ENV["HOME"] + "/.timesheet/store.yaml")
27
27
 
28
- data_file ||= ENV["TIMESHEET_DATA_FILE"]
29
- data_file ||= (ENV["HOME"] + "/.timesheet/store.yaml")
28
+ FileUtils.makedirs(File.dirname(data_file))
30
29
 
31
- FileUtils.makedirs(File.dirname(data_file))
30
+ store = YAML::Store.new(data_file)
31
+ tl = TimeLog.new(store)
32
+ ts = Timesheet.new(tl)
33
+ ts.process(command_hash)
32
34
 
33
- store = YAML::Store.new(data_file)
34
- tl = TimeLog.new(store)
35
- ts = Timesheet.new(tl)
36
- ts.process(command_hash)
35
+ rescue Exception => e
36
+ raise if command_hash[:debug]
37
+ puts e.message
37
38
 
38
- rescue Exception => e
39
- raise if command_hash[:debug]
40
- puts e.message
39
+ end
41
40
 
42
- end
41
+ def initialize(timelog)
42
+ @timelog = timelog
43
+ end
43
44
 
44
- def initialize(timelog)
45
- @timelog = timelog
46
- end
45
+ def process(command_opts)
46
+ command = command_opts[:command]
47
+ case command
48
+ when :add then process_add_command(command_opts)
49
+ when :edit then process_edit_command(command_opts)
50
+ when :delete then process_delete_command(command_opts)
51
+ when :report then process_report_command(command_opts)
52
+ else raise "Unknown command #{command}"
53
+ end
54
+ end
47
55
 
48
- def process(command_opts)
49
- command = command_opts[:command]
50
- case command
51
- when :add : process_add_command(command_opts)
52
- when :edit : process_edit_command(command_opts)
53
- when :delete : process_delete_command(command_opts)
54
- when :report : process_report_command(command_opts)
55
- else raise "Unknown command #{command}"
56
+ def process_add_command(command_opts)
57
+ te = TimeEntry.new(command_opts[:project], command_opts[:start], command_opts[:end], command_opts[:comment])
58
+ @timelog.add(te)
56
59
  end
57
- end
58
60
 
59
- def process_add_command(command_opts)
60
- te = TimeEntry.new(command_opts[:project], command_opts[:start], command_opts[:end], command_opts[:comment])
61
- @timelog.add(te)
62
- end
61
+ def process_edit_command(command_opts)
62
+ record_number = command_opts.delete(:record_number)
63
+ @timelog.update(record_number, command_opts)
64
+ entries = [@timelog.find(record_number)]
65
+ time_report = TimeReport.new(entries)
66
+ time_report.report({:dump => true})
67
+ end
63
68
 
64
- def process_edit_command(command_opts)
65
- record_number = command_opts.delete(:record_number)
66
- @timelog.update(record_number, command_opts)
67
- entries = [@timelog.find(record_number)]
68
- time_report = TimeReport.new(entries)
69
- time_report.report({:dump => true})
70
- end
69
+ def process_delete_command(command_opts)
70
+ record_number = command_opts.delete(:record_number)
71
+ @timelog.delete(record_number)
72
+ end
71
73
 
72
- def process_delete_command(command_opts)
73
- record_number = command_opts.delete(:record_number)
74
- @timelog.delete(record_number)
75
- end
74
+ def process_report_command(command_opts)
75
+ start_time = command_opts[:start]
76
+ end_time = command_opts[:end]
77
+ entries = @timelog.extract_entries(start_time, end_time)
78
+ time_report = TimeReport.new(entries)
79
+ time_report.report(command_opts)
80
+ end
76
81
 
77
- def process_report_command(command_opts)
78
- start_time = command_opts[:start]
79
- end_time = command_opts[:end]
80
- entries = @timelog.extract_entries(start_time, end_time)
81
- time_report = TimeReport.new(entries)
82
- time_report.report(command_opts)
83
82
  end
84
-
85
83
  end
86
-
@@ -1,24 +1,27 @@
1
1
  # Thanks to: http://opensoul.org/2007/2/13/ranges-include-or-overlap-with-ranges
2
2
  class Range
3
3
 
4
+ unless (0..5).respond_to?(:cover?)
5
+ alias_method :cover?, :include?
6
+ end
4
7
 
5
8
  def overlap?(range)
6
- self.include?(range.first) || range.include?(self.first)
9
+ self.cover?(range.first) || range.cover?(self.first)
7
10
  end
8
11
 
9
- alias_method :include_without_range?, :include?
12
+ alias_method :cover_without_range?, :cover?
10
13
 
11
- def include_with_range?(value)
14
+ def cover_with_range?(value)
12
15
  if value.is_a?(Range)
13
- last = value.exclude_end? ? value.last - 1 : value.last
14
- self.include?(value.first) && self.include?(last)
16
+ last = value.exclude_end? ? value.last-1 : value.last
17
+ self.cover?(value.first) && self.cover?(last)
15
18
  else
16
- include_without_range?(value)
19
+ cover_without_range?(value)
17
20
  end
18
21
  end
19
22
 
20
- alias_method :include?, :include_with_range?
23
+ alias_method :cover?, :cover_with_range?
21
24
 
22
25
  # alias_method_chain :include?, :range
23
26
 
24
- end
27
+ end
@@ -1,19 +1,21 @@
1
1
  require 'delegate'
2
2
 
3
- class ReportItem < DelegateClass(TimeEntry)
3
+ class ReportItem
4
4
 
5
5
  include Comparable
6
6
 
7
7
  def initialize( report, time_entry)
8
8
  @time_entry = time_entry
9
- super(@time_entry)
10
9
  @report = report
11
10
  end
12
11
 
13
12
  def start_time_sliced?
14
- @time_entry.to_range.include?(@report.report_start)
13
+ @time_entry.to_range.cover?(@report.report_start)
14
+ end
15
+
16
+ def project
17
+ @time_entry.project
15
18
  end
16
-
17
19
 
18
20
  def start_time
19
21
  if start_time_sliced?
@@ -30,7 +32,7 @@ class ReportItem < DelegateClass(TimeEntry)
30
32
 
31
33
 
32
34
  def end_time_sliced?
33
- @time_entry.to_range.include?(@report.report_end)
35
+ @time_entry.to_range.cover?(@report.report_end)
34
36
  end
35
37
 
36
38
  def start_slice_indication
@@ -50,7 +52,7 @@ class ReportItem < DelegateClass(TimeEntry)
50
52
  end
51
53
 
52
54
  def formatted_record_number
53
- sprintf("%5d", @time_entry.record_number)
55
+ sprintf("%5d", @time_entry.record_number || 0)
54
56
  end
55
57
 
56
58
  def formatted_start_time
@@ -0,0 +1,3 @@
1
+ module Timesheet
2
+ VERSION = "0.3.0"
3
+ end
@@ -8,10 +8,29 @@ describe Range do
8
8
  end
9
9
 
10
10
  it "should allow include?" do
11
- (1..5).include?(2..3).should be_true
11
+ (1..5).include?(2..3).should be_false
12
12
  (1..5).include?(4..8).should be_false
13
13
  (1..5).include?(3).should be_true
14
14
  (1..5).include?(6).should be_false
15
15
  end
16
16
 
17
+ context "with times" do
18
+
19
+ before(:all) do
20
+ @time = Time.now
21
+ end
22
+
23
+ it "should detect overlaps" do
24
+ (@time..@time+5).overlap?(@time+4..@time+8).should be_true
25
+ (@time...@time+5).overlap?(@time+5..@time+10).should be_false
26
+ end
27
+
28
+ it "should allow cover?" do
29
+ (@time..@time+5).cover?(@time+2..@time+3).should be_true
30
+ (@time..@time+5).cover?(@time+4..@time+8).should be_false
31
+ (@time..@time+5).cover?(@time+3).should be_true
32
+ (@time..@time+5).cover?(@time+6).should be_false
33
+ end
34
+ end
35
+
17
36
  end
@@ -0,0 +1,159 @@
1
+ require File.dirname(__FILE__) + '/spec_helper.rb'
2
+
3
+ describe ReportItem do
4
+
5
+ describe "#start_time" do
6
+
7
+ context "when constrained by the parent report" do
8
+
9
+ it "should use the report start time" do
10
+ time_entries = [ TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 18, 0, 0)) ]
11
+ time_report = TimeReport.new(time_entries)
12
+ time_report.constrain( Time.local(2009, 12, 1, 12, 0, 0), Time.local(2009, 12, 2, 12, 0, 0))
13
+
14
+ time_report.entries[0].start_time.should eql(time_report.report_start)
15
+ end
16
+
17
+ end
18
+
19
+ context "when not constrained by the parent report" do
20
+
21
+ it "should use the entry's start time" do
22
+ time_entries = [ TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 18, 0, 0)) ]
23
+ time_report = TimeReport.new(time_entries)
24
+ time_report.constrain( Time.local(2009, 11, 1, 12, 0, 0), Time.local(2009, 12, 2, 12, 0, 0))
25
+
26
+ time_report.entries[0].start_time.should eql(time_entries[0].start_time)
27
+ end
28
+ end
29
+
30
+ end
31
+
32
+ describe "#end_time" do
33
+
34
+ context "when constrained by the parent report" do
35
+
36
+ it "should use the report end time" do
37
+ time_entries = [ TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 18, 0, 0)) ]
38
+ time_report = TimeReport.new(time_entries)
39
+ time_report.constrain( Time.local(2009, 11, 1, 12, 0, 0), Time.local(2009, 12, 1, 12, 0, 0))
40
+
41
+ time_report.entries[0].end_time.should eql(time_report.report_end)
42
+ end
43
+
44
+ end
45
+
46
+ context "when not constrained by the parent report" do
47
+
48
+ it "should use the entry's end time" do
49
+ time_entries = [ TimeEntry.new("Project", Time.local(2009, 12, 1, 9, 0, 0), Time.local(2009, 12, 1, 18, 0, 0)) ]
50
+ time_report = TimeReport.new(time_entries)
51
+ time_report.constrain( Time.local(2009, 11, 1, 12, 0, 0), Time.local(2009, 12, 2, 12, 0, 0))
52
+
53
+ time_report.entries[0].end_time.should eql(time_entries[0].end_time)
54
+
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+
63
+ describe "formatting behavior" do
64
+
65
+ before :each do
66
+ @report = mock("TimeReport")
67
+ @time_entry = mock("TimeEntry")
68
+ @report_item = ReportItem.new(@report, @time_entry)
69
+ end
70
+
71
+ it "should format the record number" do
72
+ @time_entry.should_receive(:record_number).once.and_return(1)
73
+ @report_item.formatted_record_number.should eql(" 1")
74
+ end
75
+
76
+ describe "#times" do
77
+
78
+ context "when start and end times are on the same day" do
79
+ it "should show the date only once" do
80
+ entry_start = Time.local(2009, 12, 1, 9, 0, 0)
81
+ entry_end = Time.local(2009, 12, 1, 17, 0, 0)
82
+ report_start = Time.local(2009, 12, 1, 8, 0, 0)
83
+ report_end = Time.local(2009, 12, 1, 18, 0, 0)
84
+
85
+ @time_entry.should_receive(:to_range).any_number_of_times.and_return(entry_start..entry_end)
86
+ @time_entry.should_receive(:start_time).any_number_of_times.and_return(entry_start)
87
+ @time_entry.should_receive(:end_time).any_number_of_times.and_return(entry_end)
88
+
89
+ @report.should_receive(:report_start).any_number_of_times.and_return(report_start)
90
+ @report.should_receive(:report_end).any_number_of_times.and_return(report_end)
91
+
92
+ @report_item.formatted_times.should eql(" 12/01/2009 at 09:00 AM to 05:00 PM ")
93
+ end
94
+ end
95
+
96
+ context "when start and end times are on the same day and the start end end times are sliced" do
97
+ it "should show the date only once" do
98
+ entry_start = Time.local(2009, 12, 1, 9, 0, 0)
99
+ entry_end = Time.local(2009, 12, 1, 17, 0, 0)
100
+ report_start = Time.local(2009, 12, 1, 10, 0, 0)
101
+ report_end = Time.local(2009, 12, 1, 16, 0, 0)
102
+
103
+ @time_entry.should_receive(:to_range).any_number_of_times.and_return(entry_start..entry_end)
104
+ @time_entry.should_receive(:start_time).any_number_of_times.and_return(entry_start)
105
+ @time_entry.should_receive(:end_time).any_number_of_times.and_return(entry_end)
106
+
107
+ @report.should_receive(:report_start).any_number_of_times.and_return(report_start)
108
+ @report.should_receive(:report_end).any_number_of_times.and_return(report_end)
109
+
110
+ @report_item.formatted_times.should eql("<12/01/2009 at 10:00 AM to 04:00 PM>")
111
+ end
112
+ end
113
+
114
+ context "when start and end times are on different days" do
115
+ it "should show the date for both start and end" do
116
+ entry_start = Time.local(2009, 12, 1, 9, 0, 0)
117
+ entry_end = Time.local(2009, 12, 2, 18, 0, 0)
118
+ report_start = Time.local(2009, 12, 1, 8, 0, 0)
119
+ report_end = Time.local(2009, 12, 2, 19, 0, 0)
120
+
121
+ @time_entry.should_receive(:to_range).any_number_of_times.and_return(entry_start..entry_end)
122
+ @time_entry.should_receive(:start_time).any_number_of_times.and_return(entry_start)
123
+ @time_entry.should_receive(:end_time).any_number_of_times.and_return(entry_end)
124
+
125
+ @report.should_receive(:report_start).any_number_of_times.and_return(report_start)
126
+ @report.should_receive(:report_end).any_number_of_times.and_return(report_end)
127
+
128
+ @report_item.formatted_times.should eql(" 12/01/2009 at 09:00 AM to 12/02/2009 at 06:00 PM ")
129
+ end
130
+
131
+ end
132
+ end
133
+
134
+ describe "#duration" do
135
+
136
+ context "when the duration is longer than one day" do
137
+
138
+ it "should include days in the display" do
139
+ @report_item.should_receive(:duration).any_number_of_times.and_return(RichUnits::Duration.new(30.hours.to_i + 15.minutes.to_i))
140
+ # @report_item.should_receive(:duration).any_number_of_times.and_return(RichUnits::Duration.new(30.hours.to_i + 15.minutes.to_i))
141
+ @report_item.formatted_duration.should eql("1 Days 6h 15m")
142
+ end
143
+
144
+ end
145
+
146
+ context "when the duration is less than one day" do
147
+
148
+ it "should not include days in the display" do
149
+ # report_item = ReportItem.new(@report, @time_entry)
150
+ @report_item.stub(:duration).any_number_of_times.and_return(RichUnits::Duration.new(12.hours.to_i + 15.minutes.to_i))
151
+
152
+ # report_item.should_receive(:duration).any_number_of_times.and_return(RichUnits::Duration.new(12.hours.to_i + 15.minutes.to_i))
153
+ @report_item.formatted_duration.should eql("12h 15m")
154
+ end
155
+ end
156
+
157
+ end
158
+
159
+ end
@@ -1,17 +1,4 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems' unless ENV['NO_RUBYGEMS']
5
- gem 'rspec'
6
- require 'spec'
7
- end
8
-
9
1
  $:.unshift(File.dirname(__FILE__) + '/../lib')
10
2
 
11
3
  require 'timesheet'
12
4
 
13
-
14
- #Spec::Runner.configure do |config|
15
- # config.mock_with :mocha
16
- #end
17
-
@@ -48,7 +48,7 @@ describe TimesheetParser do
48
48
  end
49
49
 
50
50
  it "should allow comment to be optional" do
51
- hash = TimesheetParser.parse(%w[add -p a\ project\ name --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
51
+ hash = TimesheetParser.parse(%w[add -p a\ project\ name --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
52
52
  hash[:command].should eql(:add)
53
53
  hash[:project].should eql("a project name")
54
54
  hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
@@ -79,7 +79,7 @@ describe TimesheetParser do
79
79
  end
80
80
 
81
81
  it "should accept a start and end time" do
82
- hash = TimesheetParser.parse(%w[list --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
82
+ hash = TimesheetParser.parse(%w[list --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
83
83
  hash[:command].should eql(:report)
84
84
  hash[:detail].should be_true
85
85
  hash[:start].should eql(Time.local(2009, 12, 1, 11, 0, 0))
@@ -95,11 +95,11 @@ describe TimesheetParser do
95
95
  end
96
96
 
97
97
  it "should fail if start date and --today are used" do
98
- lambda {TimesheetParser.parse(%w[list --today --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])}.should raise_error SystemExit
98
+ lambda {TimesheetParser.parse(%w[list --today --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])}.should raise_error SystemExit
99
99
  end
100
100
 
101
101
  it "should fail if start date is missing end date" do
102
- lambda {TimesheetParser.parse(%w[list --start 12/1/2009\at\ 11:00\ am])}.should raise_error SystemExit
102
+ lambda {TimesheetParser.parse(%w[list --start 12/1/2009\ at\ 11:00\ am])}.should raise_error SystemExit
103
103
  end
104
104
 
105
105
  end
@@ -114,7 +114,7 @@ describe TimesheetParser do
114
114
  end
115
115
 
116
116
  it "should parse a valid complete edit command" do
117
- hash = TimesheetParser.parse(%w[edit -r 100 -p a\ project\ name --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm --comment a\ comment])
117
+ hash = TimesheetParser.parse(%w[edit -r 100 -p a\ project\ name --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm --comment a\ comment])
118
118
  hash[:command].should eql(:edit)
119
119
  hash[:record_number].should eql(100)
120
120
  hash[:project].should eql("a project name")
@@ -144,7 +144,7 @@ describe TimesheetParser do
144
144
  end
145
145
 
146
146
  it "should allow just start time" do
147
- hash = TimesheetParser.parse(%w[edit -r 1 -s 12/1/2009\at\ 11:00\ am])
147
+ hash = TimesheetParser.parse(%w[edit -r 1 -s 12/1/2009\ at\ 11:00\ am])
148
148
  hash[:command].should eql(:edit)
149
149
  hash[:record_number].should eql(1)
150
150
  hash[:project].should be_nil
@@ -154,7 +154,7 @@ describe TimesheetParser do
154
154
  end
155
155
 
156
156
  it "should allow just end time" do
157
- hash = TimesheetParser.parse(%w[edit -r 1 -e 12/1/2009\at\ 2:00\ pm])
157
+ hash = TimesheetParser.parse(%w[edit -r 1 -e 12/1/2009\ at\ 2:00\ pm])
158
158
  hash[:command].should eql(:edit)
159
159
  hash[:record_number].should eql(1)
160
160
  hash[:project].should be_nil
@@ -192,7 +192,7 @@ describe TimesheetParser do
192
192
  end
193
193
 
194
194
  it "should parse a valid complete report command" do
195
- hash = TimesheetParser.parse(%w[report --summary --start 12/1/2009\at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
195
+ hash = TimesheetParser.parse(%w[report --summary --start 12/1/2009\ at\ 11:00\ am --end 12/1/2009\ at\ 2:00\ pm])
196
196
  hash[:command].should eql(:report)
197
197
  hash[:summary].should be_true
198
198
  hash[:detail].should be_false
@@ -16,9 +16,9 @@ describe Timesheet do
16
16
 
17
17
  command_hash.should_receive(:[]).with(:debug).once.and_return(nil)
18
18
 
19
- Timesheet.should_receive(:puts).with("Cannot determine location for data. Try timesheet --help for details.").once.and_return(nil)
19
+ Timesheet::Timesheet.should_receive(:puts).with("Cannot determine location for data. Try timesheet --help for details.").once.and_return(nil)
20
20
 
21
- Timesheet.run(params)
21
+ Timesheet::Timesheet.run(params)
22
22
 
23
23
  end
24
24
 
@@ -43,10 +43,10 @@ describe Timesheet do
43
43
 
44
44
  YAML::Store.should_receive(:new).with(expected_timesheet_data_file).once.and_return(store)
45
45
  TimeLog.should_receive(:new).with(store).once.and_return(time_log)
46
- Timesheet.should_receive(:new).with(time_log).once.and_return(time_sheet)
46
+ Timesheet::Timesheet.should_receive(:new).with(time_log).once.and_return(time_sheet)
47
47
  time_sheet.should_receive(:process).with(command_hash)
48
48
 
49
- Timesheet.run(params)
49
+ Timesheet::Timesheet.run(params)
50
50
 
51
51
  end
52
52
 
@@ -72,10 +72,10 @@ describe Timesheet do
72
72
 
73
73
  YAML::Store.should_receive(:new).with(expected_data_file).once.and_return(store)
74
74
  TimeLog.should_receive(:new).with(store).once.and_return(time_log)
75
- Timesheet.should_receive(:new).with(time_log).once.and_return(time_sheet)
75
+ Timesheet::Timesheet.should_receive(:new).with(time_log).once.and_return(time_sheet)
76
76
  time_sheet.should_receive(:process).with(command_hash)
77
77
 
78
- Timesheet.run(params)
78
+ Timesheet::Timesheet.run(params)
79
79
 
80
80
  end
81
81
 
@@ -86,7 +86,7 @@ describe Timesheet do
86
86
  before :each do
87
87
  @command = mock("command")
88
88
  @timelog = mock("timelog")
89
- @timesheet = Timesheet.new(@timelog)
89
+ @timesheet = Timesheet::Timesheet.new(@timelog)
90
90
  end
91
91
 
92
92
  it "should dispatch to the proper command handler" do
@@ -114,7 +114,7 @@ describe Timesheet do
114
114
  it "should perform an add" do
115
115
  command = mock("add command")
116
116
  timelog = mock("timelog")
117
- timesheet = Timesheet.new(timelog)
117
+ timesheet = Timesheet::Timesheet.new(timelog)
118
118
 
119
119
  project = mock("project")
120
120
  start_time = mock("start time")
@@ -138,7 +138,7 @@ describe Timesheet do
138
138
  it "should perform an edit" do
139
139
  command = mock("dump command")
140
140
  timelog = mock("timelog")
141
- timesheet = Timesheet.new(timelog)
141
+ timesheet = Timesheet::Timesheet.new(timelog)
142
142
  time_report = mock("time report")
143
143
  entries = mock("entries")
144
144
 
@@ -158,7 +158,7 @@ describe Timesheet do
158
158
  it "should perform a delete" do
159
159
  command = mock("delete command")
160
160
  timelog = mock("timelog")
161
- timesheet = Timesheet.new(timelog)
161
+ timesheet = Timesheet::Timesheet.new(timelog)
162
162
 
163
163
  command.should_receive(:delete).with(:record_number).once.and_return(100)
164
164
  timelog.should_receive(:delete).with(100)
@@ -177,7 +177,7 @@ describe Timesheet do
177
177
  end_time = mock("end time")
178
178
  entries = mock("entries")
179
179
  time_report = mock("time report")
180
- timesheet = Timesheet.new(timelog)
180
+ timesheet = Timesheet::Timesheet.new(timelog)
181
181
 
182
182
  command.should_receive(:[]).with(:start).once.and_return(start_time)
183
183
  command.should_receive(:[]).with(:end).once.and_return(end_time)
@@ -0,0 +1,32 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "timesheet/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "timesheet"
7
+ s.version = Timesheet::VERSION
8
+ s.date = "2010-10-25"
9
+ s.authors = ["John F. Schank III"]
10
+ s.email = ["jschank@mac.com"]
11
+ s.homepage = "http://github.com/jschank/timesheet"
12
+ s.summary = "Timesheet is simple ruby application for tracking time spent on projects"
13
+ s.default_executable = "timesheet"
14
+ s.description = "Timesheet is simple ruby application for tracking time spent on projects.
15
+ It is a console application that uses a simple text file storage back-end (YAML::Store)
16
+
17
+ The main idea is to be able to produce reports of hours spent, such that I can use geektool to display the reports."
18
+
19
+ s.rubyforge_project = "timesheet"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+
26
+ s.add_development_dependency "rspec"
27
+ s.add_development_dependency "syntax"
28
+
29
+ s.add_runtime_dependency "richunits"
30
+ s.add_runtime_dependency "chronic"
31
+
32
+ end
metadata CHANGED
@@ -1,219 +1,96 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: timesheet
3
- version: !ruby/object:Gem::Version
4
- version: 0.2.8
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ prerelease:
5
6
  platform: ruby
6
- authors:
7
+ authors:
7
8
  - John F. Schank III
8
9
  autorequire:
9
10
  bindir: bin
10
11
  cert_chain: []
11
-
12
- date: 2010-03-08 00:00:00 -05:00
13
- default_executable:
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
16
- name: activesupport
17
- type: :runtime
18
- version_requirement:
19
- version_requirements: !ruby/object:Gem::Requirement
20
- requirements:
21
- - - ">="
22
- - !ruby/object:Gem::Version
23
- version: "0"
24
- version:
25
- - !ruby/object:Gem::Dependency
26
- name: archive-tar-minitar
27
- type: :runtime
28
- version_requirement:
29
- version_requirements: !ruby/object:Gem::Requirement
30
- requirements:
31
- - - ">="
32
- - !ruby/object:Gem::Version
33
- version: "0"
34
- version:
35
- - !ruby/object:Gem::Dependency
36
- name: chronic
37
- type: :runtime
38
- version_requirement:
39
- version_requirements: !ruby/object:Gem::Requirement
40
- requirements:
41
- - - ">="
42
- - !ruby/object:Gem::Version
43
- version: "0"
44
- version:
45
- - !ruby/object:Gem::Dependency
46
- name: hoe
47
- type: :runtime
48
- version_requirement:
49
- version_requirements: !ruby/object:Gem::Requirement
50
- requirements:
51
- - - ">="
52
- - !ruby/object:Gem::Version
53
- version: "0"
54
- version:
55
- - !ruby/object:Gem::Dependency
56
- name: json_pure
57
- type: :runtime
58
- version_requirement:
59
- version_requirements: !ruby/object:Gem::Requirement
60
- requirements:
61
- - - ">="
62
- - !ruby/object:Gem::Version
63
- version: "0"
64
- version:
65
- - !ruby/object:Gem::Dependency
66
- name: newgem
67
- type: :runtime
68
- version_requirement:
69
- version_requirements: !ruby/object:Gem::Requirement
70
- requirements:
71
- - - ">="
72
- - !ruby/object:Gem::Version
73
- version: "0"
74
- version:
75
- - !ruby/object:Gem::Dependency
76
- name: rake
77
- type: :runtime
78
- version_requirement:
79
- version_requirements: !ruby/object:Gem::Requirement
80
- requirements:
81
- - - ">="
82
- - !ruby/object:Gem::Version
83
- version: "0"
84
- version:
85
- - !ruby/object:Gem::Dependency
86
- name: RedCloth
87
- type: :runtime
88
- version_requirement:
89
- version_requirements: !ruby/object:Gem::Requirement
90
- requirements:
91
- - - ">="
92
- - !ruby/object:Gem::Version
93
- version: "0"
94
- version:
95
- - !ruby/object:Gem::Dependency
96
- name: richunits
97
- type: :runtime
98
- version_requirement:
99
- version_requirements: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: "0"
104
- version:
105
- - !ruby/object:Gem::Dependency
12
+ date: 2010-10-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
106
15
  name: rspec
107
- type: :runtime
108
- version_requirement:
109
- version_requirements: !ruby/object:Gem::Requirement
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: "0"
114
- version:
115
- - !ruby/object:Gem::Dependency
116
- name: rubigen
117
- type: :runtime
118
- version_requirement:
119
- version_requirements: !ruby/object:Gem::Requirement
120
- requirements:
121
- - - ">="
122
- - !ruby/object:Gem::Version
123
- version: "0"
124
- version:
125
- - !ruby/object:Gem::Dependency
126
- name: rubyforge
127
- type: :runtime
128
- version_requirement:
129
- version_requirements: !ruby/object:Gem::Requirement
130
- requirements:
131
- - - ">="
132
- - !ruby/object:Gem::Version
133
- version: "0"
134
- version:
135
- - !ruby/object:Gem::Dependency
16
+ requirement: &70346204068560 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70346204068560
25
+ - !ruby/object:Gem::Dependency
136
26
  name: syntax
27
+ requirement: &70346204068080 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70346204068080
36
+ - !ruby/object:Gem::Dependency
37
+ name: richunits
38
+ requirement: &70346204067440 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
137
44
  type: :runtime
138
- version_requirement:
139
- version_requirements: !ruby/object:Gem::Requirement
140
- requirements:
141
- - - ">="
142
- - !ruby/object:Gem::Version
143
- version: "0"
144
- version:
145
- - !ruby/object:Gem::Dependency
146
- name: transaction-simple
45
+ prerelease: false
46
+ version_requirements: *70346204067440
47
+ - !ruby/object:Gem::Dependency
48
+ name: chronic
49
+ requirement: &70346204066860 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
147
55
  type: :runtime
148
- version_requirement:
149
- version_requirements: !ruby/object:Gem::Requirement
150
- requirements:
151
- - - ">="
152
- - !ruby/object:Gem::Version
153
- version: "0"
154
- version:
155
- - !ruby/object:Gem::Dependency
156
- name: rubyforge
157
- type: :development
158
- version_requirement:
159
- version_requirements: !ruby/object:Gem::Requirement
160
- requirements:
161
- - - ">="
162
- - !ruby/object:Gem::Version
163
- version: 2.0.3
164
- version:
165
- - !ruby/object:Gem::Dependency
166
- name: gemcutter
167
- type: :development
168
- version_requirement:
169
- version_requirements: !ruby/object:Gem::Requirement
170
- requirements:
171
- - - ">="
172
- - !ruby/object:Gem::Version
173
- version: 0.3.0
174
- version:
175
- - !ruby/object:Gem::Dependency
176
- name: hoe
177
- type: :development
178
- version_requirement:
179
- version_requirements: !ruby/object:Gem::Requirement
180
- requirements:
181
- - - ">="
182
- - !ruby/object:Gem::Version
183
- version: 2.5.0
184
- version:
185
- description: |-
186
- <i>Timesheet</i> is simple ruby application for tracking time spent on projects.
56
+ prerelease: false
57
+ version_requirements: *70346204066860
58
+ description: ! 'Timesheet is simple ruby application for tracking time spent on projects.
59
+
187
60
  It is a console application that uses a simple text file storage back-end (YAML::Store)
188
-
189
- The main idea is to be able to produce reports of hours spent, such that I can use geektool to display the reports.
190
- email:
61
+
62
+
63
+ The main idea is to be able to produce reports of hours spent, such that I can use
64
+ geektool to display the reports.'
65
+ email:
191
66
  - jschank@mac.com
192
- executables:
67
+ executables:
193
68
  - timesheet
194
69
  extensions: []
195
-
196
- extra_rdoc_files:
197
- - History.txt
198
- - Manifest.txt
199
- files:
200
- - History.txt
201
- - Manifest.txt
70
+ extra_rdoc_files: []
71
+ files:
72
+ - .gitignore
73
+ - .rdebugrc
74
+ - .rvmrc
75
+ - Gemfile
202
76
  - README.rdoc
203
77
  - Rakefile
204
78
  - bin/timesheet
205
79
  - lib/timesheet.rb
206
80
  - lib/timesheet/range_extensions.rb
207
- - lib/timesheet/time_entry.rb
208
81
  - lib/timesheet/report_item.rb
82
+ - lib/timesheet/time_entry.rb
209
83
  - lib/timesheet/time_log.rb
210
84
  - lib/timesheet/time_report.rb
211
85
  - lib/timesheet/timesheet_parser.rb
212
86
  - lib/timesheet/trollop.rb
213
- - script/console
214
- - script/destroy
215
- - script/generate
87
+ - lib/timesheet/version.rb
88
+ - notes/Creating a RubyGem Package | 5dollarwhitebox.org.webloc
89
+ - notes/Gem--Specification Reference | RubyGems Manuals.webloc
90
+ - notes/Kuiper DevBlog- Day 89- The Gemification.webloc
91
+ - notes/Kuiper DevBlog- Day 90- Gemification 2, the revenge.webloc
216
92
  - spec/range_extensions_spec.rb
93
+ - spec/report_item_spec.rb
217
94
  - spec/spec.opts
218
95
  - spec/spec_helper.rb
219
96
  - spec/time_entry_spec.rb
@@ -221,35 +98,38 @@ files:
221
98
  - spec/time_report_spec.rb
222
99
  - spec/timesheet_parser_spec.rb
223
100
  - spec/timesheet_spec.rb
224
- - tasks/rspec.rake
225
- has_rdoc: true
101
+ - timesheet.gemspec
226
102
  homepage: http://github.com/jschank/timesheet
227
103
  licenses: []
228
-
229
104
  post_install_message:
230
- rdoc_options:
231
- - --main
232
- - README.rdoc
233
- require_paths:
105
+ rdoc_options: []
106
+ require_paths:
234
107
  - lib
235
- required_ruby_version: !ruby/object:Gem::Requirement
236
- requirements:
237
- - - ">="
238
- - !ruby/object:Gem::Version
239
- version: "0"
240
- version:
241
- required_rubygems_version: !ruby/object:Gem::Requirement
242
- requirements:
243
- - - ">="
244
- - !ruby/object:Gem::Version
245
- version: "0"
246
- version:
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ! '>='
112
+ - !ruby/object:Gem::Version
113
+ version: '0'
114
+ required_rubygems_version: !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ! '>='
118
+ - !ruby/object:Gem::Version
119
+ version: '0'
247
120
  requirements: []
248
-
249
121
  rubyforge_project: timesheet
250
- rubygems_version: 1.3.5
122
+ rubygems_version: 1.8.10
251
123
  signing_key:
252
124
  specification_version: 3
253
- summary: <i>Timesheet</i> is simple ruby application for tracking time spent on projects
254
- test_files: []
255
-
125
+ summary: Timesheet is simple ruby application for tracking time spent on projects
126
+ test_files:
127
+ - spec/range_extensions_spec.rb
128
+ - spec/report_item_spec.rb
129
+ - spec/spec.opts
130
+ - spec/spec_helper.rb
131
+ - spec/time_entry_spec.rb
132
+ - spec/time_log_spec.rb
133
+ - spec/time_report_spec.rb
134
+ - spec/timesheet_parser_spec.rb
135
+ - spec/timesheet_spec.rb
@@ -1,8 +0,0 @@
1
- === 0.2.4 2010-02-07
2
-
3
- * removed dependency on ruport
4
-
5
- === 0.0.1 2009-11-29
6
-
7
- * 1 major enhancement:
8
- * Initial release
@@ -1,25 +0,0 @@
1
- History.txt
2
- Manifest.txt
3
- README.rdoc
4
- Rakefile
5
- bin/timesheet
6
- lib/timesheet.rb
7
- lib/timesheet/range_extensions.rb
8
- lib/timesheet/time_entry.rb
9
- lib/timesheet/report_item.rb
10
- lib/timesheet/time_log.rb
11
- lib/timesheet/time_report.rb
12
- lib/timesheet/timesheet_parser.rb
13
- lib/timesheet/trollop.rb
14
- script/console
15
- script/destroy
16
- script/generate
17
- spec/range_extensions_spec.rb
18
- spec/spec.opts
19
- spec/spec_helper.rb
20
- spec/time_entry_spec.rb
21
- spec/time_log_spec.rb
22
- spec/time_report_spec.rb
23
- spec/timesheet_parser_spec.rb
24
- spec/timesheet_spec.rb
25
- tasks/rspec.rake
@@ -1,10 +0,0 @@
1
- #!/usr/bin/env ruby
2
- # File: script/console
3
- irb = RUBY_PLATFORM =~ /(:?mswin|mingw)/ ? 'irb.bat' : 'irb'
4
-
5
- libs = " -r irb/completion"
6
- # Perhaps use a console_lib to store any extra methods I may want available in the cosole
7
- # libs << " -r #{File.dirname(__FILE__) + '/../lib/console_lib/console_logger.rb'}"
8
- libs << " -r #{File.dirname(__FILE__) + '/../lib/timesheet.rb'}"
9
- puts "Loading timesheet gem"
10
- exec "#{irb} #{libs} --simple-prompt"
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
- APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
-
4
- begin
5
- require 'rubigen'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'rubigen'
9
- end
10
- require 'rubigen/scripts/destroy'
11
-
12
- ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
- RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
- RubiGen::Scripts::Destroy.new.run(ARGV)
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
- APP_ROOT = File.expand_path(File.join(File.dirname(__FILE__), '..'))
3
-
4
- begin
5
- require 'rubigen'
6
- rescue LoadError
7
- require 'rubygems'
8
- require 'rubigen'
9
- end
10
- require 'rubigen/scripts/generate'
11
-
12
- ARGV.shift if ['--help', '-h'].include?(ARGV[0])
13
- RubiGen::Base.use_component_sources! [:rubygems, :newgem, :newgem_theme, :test_unit]
14
- RubiGen::Scripts::Generate.new.run(ARGV)
@@ -1,21 +0,0 @@
1
- begin
2
- require 'spec'
3
- rescue LoadError
4
- require 'rubygems' unless ENV['NO_RUBYGEMS']
5
- require 'spec'
6
- end
7
- begin
8
- require 'spec/rake/spectask'
9
- rescue LoadError
10
- puts <<-EOS
11
- To use rspec for testing you must install rspec gem:
12
- gem install rspec
13
- EOS
14
- exit(0)
15
- end
16
-
17
- desc "Run the specs under spec/models"
18
- Spec::Rake::SpecTask.new do |t|
19
- t.spec_opts = ['--options', "spec/spec.opts"]
20
- t.spec_files = FileList['spec/**/*_spec.rb']
21
- end