timesheet 0.2.8 → 0.3.0

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