timetrap 1.15.2 → 1.15.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.
- checksums.yaml +4 -4
- data/.github/pull_request_template.md +29 -0
- data/.github/workflows/rspec.yml +16 -0
- data/.gitignore +1 -0
- data/.rspec +1 -2
- data/README.md +34 -1
- data/completions/bash/timetrap-autocomplete.bash +2 -1
- data/lib/timetrap/cli.rb +20 -5
- data/lib/timetrap/formatters/csv.rb +5 -1
- data/lib/timetrap/formatters/ical.rb +8 -16
- data/lib/timetrap/formatters/json.rb +6 -1
- data/lib/timetrap/version.rb +1 -1
- data/lib/timetrap.rb +5 -2
- data/spec/spec_helper.rb +40 -0
- data/spec/support/local_time.rb +7 -0
- data/spec/support/with_rounding_on.rb +9 -0
- data/spec/support/with_stubbed_config.rb +7 -0
- data/spec/timetrap_spec.rb +63 -51
- data/timetrap.gemspec +3 -3
- metadata +22 -12
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0c2feb8354a6c8436c47ab48cba74b9eb7588424ee87b890d9c6a62746b1170c
|
4
|
+
data.tar.gz: 28d01e6457a8fd22fe8b40ea7e5aec0c63a24eab662b5b2b455d10f06eccc0f9
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: cfd063c2208a259f22adbc42a4b8f018f7b72818edb585317eab089285d2675059d930bc90064bf579b756f2d28800e6a7ee4cccc83077d5d4e1d1dc8a463d85
|
7
|
+
data.tar.gz: 05413ff91bdcee062e5bd18256178d943db285b5dbc5e1cdffc62ac921e726678f9360ce5dd7cf41be1bb5a675c2803a65f1e3af78492037f68ed33a6cd1e94e
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<!--- Provide a general summary of your changes in the Title above -->
|
2
|
+
|
3
|
+
## Description
|
4
|
+
<!--- Describe your changes in detail -->
|
5
|
+
|
6
|
+
## Motivation and Context
|
7
|
+
<!--- Why is this change required? What problem does it solve? -->
|
8
|
+
<!--- If it fixes an open issue, please link to the issue here. -->
|
9
|
+
|
10
|
+
## How Has This Been Tested?
|
11
|
+
<!--- Please describe in detail how you tested your changes. -->
|
12
|
+
<!--- Include details of your testing environment, and the tests you ran to -->
|
13
|
+
<!--- see how your change affects other areas of the code, etc. -->
|
14
|
+
|
15
|
+
## Screenshots (if appropriate):
|
16
|
+
|
17
|
+
## Types of changes
|
18
|
+
<!--- What types of changes does your code introduce? Put an `x` in all the boxes that apply: -->
|
19
|
+
- [ ] Bug fix (non-breaking change which fixes an issue)
|
20
|
+
- [ ] New feature (non-breaking change which adds functionality)
|
21
|
+
- [ ] Breaking change (fix or feature that would cause existing functionality to change)
|
22
|
+
|
23
|
+
## Checklist:
|
24
|
+
<!--- Go over all the following points, and put an `x` in all the boxes that apply. -->
|
25
|
+
<!--- If you're unsure about any of these, don't hesitate to ask. We're here to help! -->
|
26
|
+
- [ ] My code follows the code style of this project.
|
27
|
+
- [ ] I have updated the documentation accordingly.
|
28
|
+
- [ ] I have added tests to cover my changes.
|
29
|
+
- [ ] All new and existing tests passed.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
name: rspec
|
2
|
+
on:
|
3
|
+
- push
|
4
|
+
- pull_request
|
5
|
+
|
6
|
+
jobs:
|
7
|
+
test:
|
8
|
+
name: Run Rspec
|
9
|
+
runs-on: ubuntu-latest
|
10
|
+
steps:
|
11
|
+
- uses: actions/checkout@v2
|
12
|
+
- uses: ruby/setup-ruby@v1
|
13
|
+
with:
|
14
|
+
ruby-version: '2.7'
|
15
|
+
- run: bundle install
|
16
|
+
- run: rspec spec
|
data/.gitignore
CHANGED
data/.rspec
CHANGED
@@ -1,2 +1 @@
|
|
1
|
-
--
|
2
|
-
--profile
|
1
|
+
--require spec_helper
|
data/README.md
CHANGED
@@ -13,6 +13,15 @@ To install:
|
|
13
13
|
|
14
14
|
This will place a ``t`` executable in your path.
|
15
15
|
|
16
|
+
If you would like to build the latest master from source:
|
17
|
+
|
18
|
+
$ git clone https://github.com/samg/timetrap
|
19
|
+
$ cd timetrap
|
20
|
+
$ gem build timetrap
|
21
|
+
$ gem install timetrap_X.X.X.gem
|
22
|
+
|
23
|
+
If you have errors while parsing the documentation, use `--no-document` option when installing the gem, or other option is to `gem install rdoc` before installing the `timetrap`. This is a known issue from [rdoc](https://github.com/ruby/rdoc/commit/5f9603f35d8e520c761015810c005e4a5beb97c3)
|
24
|
+
|
16
25
|
### Basic Usage
|
17
26
|
|
18
27
|
$ # get help
|
@@ -64,7 +73,7 @@ If you make a mistake use the `edit` command.
|
|
64
73
|
You check out with the `out` command.
|
65
74
|
|
66
75
|
$ t out
|
67
|
-
Checked out of sheet "coding"
|
76
|
+
Checked out of entry "document timetrap" in sheet "coding"
|
68
77
|
|
69
78
|
Running `edit` when you're checked out will edit the last entry you checked out
|
70
79
|
of.
|
@@ -512,6 +521,7 @@ fpath=(/path/to/timetrap-1.x.y/gem/completions/zsh $fpath)
|
|
512
521
|
```
|
513
522
|
|
514
523
|
#### Notes editing
|
524
|
+
|
515
525
|
If you use the note_editor setting, then it is possible to use
|
516
526
|
an editor for writing your notes. If you use a non terminal based
|
517
527
|
editor (like atom, sublime etc.) then you will need to make timetrap
|
@@ -522,6 +532,29 @@ As of when this command was added, for atom you would use `atom --wait`
|
|
522
532
|
and for sublime `subl -w`. If you use a console based editor (vim, emacs,
|
523
533
|
nano) then it should just work.
|
524
534
|
|
535
|
+
Development
|
536
|
+
-----------
|
537
|
+
|
538
|
+
Get `bundler` in case you don't have it:
|
539
|
+
|
540
|
+
gem install bundler
|
541
|
+
|
542
|
+
Set a local path for the project's dependencies:
|
543
|
+
|
544
|
+
bundle config set --local path 'vendor/bundle'
|
545
|
+
|
546
|
+
Install timetrap's dependencies:
|
547
|
+
|
548
|
+
bundle install
|
549
|
+
|
550
|
+
Now you can run your local timetrap installation:
|
551
|
+
|
552
|
+
bundle exec t
|
553
|
+
|
554
|
+
Or run the test suite:
|
555
|
+
|
556
|
+
bundle exec rspec
|
557
|
+
|
525
558
|
Special Thanks
|
526
559
|
--------------
|
527
560
|
|
@@ -3,8 +3,9 @@ _timetrap ()
|
|
3
3
|
{
|
4
4
|
cur="${COMP_WORDS[COMP_CWORD]}"
|
5
5
|
cmd="${COMP_WORDS[1]}"
|
6
|
+
|
6
7
|
if [[ ( $cmd = s* || $cmd = d* ) && "$COMP_CWORD" = 2 ]]; then
|
7
|
-
COMPREPLY=($(compgen -W "$(echo "select distinct sheet from entries where sheet not like '\_%';" |
|
8
|
+
COMPREPLY=($(compgen -W "$(echo "select distinct sheet from entries where sheet not like '\_%';" | t b)" $cur))
|
8
9
|
return
|
9
10
|
elif [[ "$COMP_CWORD" = 1 ]]; then
|
10
11
|
CMDS="archive backend configure display edit in kill list now out resume sheet week month"
|
data/lib/timetrap/cli.rb
CHANGED
@@ -71,6 +71,7 @@ COMMAND is one of:
|
|
71
71
|
-z, --append Append to the current note instead of replacing it
|
72
72
|
the delimiter between appended notes is
|
73
73
|
configurable (see configure)
|
74
|
+
-c, --clear Allow an empty note, can be used to clear existing notes
|
74
75
|
-m, --move <sheet> Move to another sheet
|
75
76
|
|
76
77
|
* in - Start the timer for the current timesheet.
|
@@ -247,14 +248,18 @@ COMMAND is one of:
|
|
247
248
|
end
|
248
249
|
|
249
250
|
if Config['note_editor']
|
250
|
-
if args['-
|
251
|
+
if args['-c']
|
252
|
+
entry.update :note => ''
|
253
|
+
elsif args['-z']
|
251
254
|
note = [entry.note, get_note_from_external_editor].join(Config['append_notes_delimiter'])
|
252
255
|
entry.update :note => note
|
253
256
|
elsif editing_a_note?
|
254
257
|
entry.update :note => get_note_from_external_editor(entry.note)
|
255
258
|
end
|
256
259
|
else
|
257
|
-
if
|
260
|
+
if args['-c']
|
261
|
+
entry.update :note => ''
|
262
|
+
elsif unused_args =~ /.+/
|
258
263
|
note = unused_args
|
259
264
|
if args['-z']
|
260
265
|
note = [entry.note, note].join(Config['append_notes_delimiter'])
|
@@ -324,7 +329,9 @@ COMMAND is one of:
|
|
324
329
|
def out
|
325
330
|
if Config['auto_checkout']
|
326
331
|
stopped = Timer.stop_all(args['-a']).each do |checked_out_of|
|
327
|
-
|
332
|
+
note = Timer.last_checkout.note
|
333
|
+
entry = note_blank?(note) ? Timer.last_checkout.id : note.inspect
|
334
|
+
warn "Checked out of entry #{entry} in sheet #{checked_out_of.sheet.inspect}."
|
328
335
|
end
|
329
336
|
if stopped.empty?
|
330
337
|
warn "No running entries to stop."
|
@@ -332,7 +339,9 @@ COMMAND is one of:
|
|
332
339
|
else
|
333
340
|
sheet = sheet_name_from_string(unused_args)
|
334
341
|
if Timer.stop sheet, args['-a']
|
335
|
-
|
342
|
+
note = Timer.last_checkout.note
|
343
|
+
entry = note_blank?(note) ? Timer.last_checkout.id : note.inspect
|
344
|
+
warn "Checked out of entry #{entry} in sheet #{sheet.inspect}."
|
336
345
|
else
|
337
346
|
warn "No running entry on sheet #{sheet.inspect}."
|
338
347
|
end
|
@@ -390,8 +399,10 @@ COMMAND is one of:
|
|
390
399
|
Timer.current_sheet = sheet
|
391
400
|
if Timer.last_sheet == sheet
|
392
401
|
warn "Already on sheet #{sheet.inspect}"
|
393
|
-
|
402
|
+
elsif Entry.sheets.include?(sheet)
|
394
403
|
warn "Switching to sheet #{sheet.inspect}"
|
404
|
+
else
|
405
|
+
warn "Switching to sheet #{sheet.inspect} (new sheet)"
|
395
406
|
end
|
396
407
|
end
|
397
408
|
|
@@ -477,6 +488,10 @@ COMMAND is one of:
|
|
477
488
|
|
478
489
|
private
|
479
490
|
|
491
|
+
def note_blank?(note)
|
492
|
+
note.inspect.to_s.gsub('"', '').strip.size.zero?
|
493
|
+
end
|
494
|
+
|
480
495
|
def unused_args
|
481
496
|
args.unused.join(' ')
|
482
497
|
end
|
@@ -6,7 +6,7 @@ module Timetrap
|
|
6
6
|
def initialize entries
|
7
7
|
@output = entries.inject("start,end,note,sheet\n") do |out, e|
|
8
8
|
next(out) unless e.end
|
9
|
-
out << %|"#{e.start.strftime(time_format)}","#{e.end.strftime(time_format)}","#{e.note}","#{e.sheet}"\n|
|
9
|
+
out << %|"#{e.start.strftime(time_format)}","#{e.end.strftime(time_format)}","#{escape(e.note)}","#{e.sheet}"\n|
|
10
10
|
end
|
11
11
|
end
|
12
12
|
|
@@ -14,6 +14,10 @@ module Timetrap
|
|
14
14
|
def time_format
|
15
15
|
"%Y-%m-%d %H:%M:%S"
|
16
16
|
end
|
17
|
+
|
18
|
+
def escape(note)
|
19
|
+
note.gsub %q{"}, %q{""}
|
20
|
+
end
|
17
21
|
end
|
18
22
|
end
|
19
23
|
end
|
@@ -4,7 +4,7 @@ rescue LoadError
|
|
4
4
|
raise <<-ERR
|
5
5
|
The icalendar gem must be installed for ical output.
|
6
6
|
To install it:
|
7
|
-
$ [sudo] gem install icalendar
|
7
|
+
$ [sudo] gem install icalendar
|
8
8
|
ERR
|
9
9
|
end
|
10
10
|
|
@@ -22,21 +22,13 @@ module Timetrap
|
|
22
22
|
end
|
23
23
|
|
24
24
|
def initialize entries
|
25
|
-
entries.each do |
|
26
|
-
next unless
|
27
|
-
calendar.event do
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
dtstart > other.dtstart ? 1 : 0
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
|
-
dtstart DateTime.parse(e.start.to_s)
|
37
|
-
dtend DateTime.parse(e.end.to_s)
|
38
|
-
summary e.note
|
39
|
-
description e.note
|
25
|
+
entries.each do |entry|
|
26
|
+
next unless entry.end
|
27
|
+
calendar.event do |e|
|
28
|
+
e.dtstart = DateTime.parse(entry.start.to_s)
|
29
|
+
e.dtend = DateTime.parse(entry.end.to_s)
|
30
|
+
e.summary = entry.note
|
31
|
+
e.description = entry.note
|
40
32
|
end
|
41
33
|
end
|
42
34
|
calendar.publish
|
@@ -16,7 +16,12 @@ module Timetrap
|
|
16
16
|
def initialize entries
|
17
17
|
@output = entries.map do |e|
|
18
18
|
next unless e.end
|
19
|
-
|
19
|
+
|
20
|
+
e.values.inject({}) do |h, (k,v)|
|
21
|
+
h[k] = v
|
22
|
+
h[k] = e.public_send(k) if %i[end start].include?(k)
|
23
|
+
h
|
24
|
+
end
|
20
25
|
end.compact.to_json
|
21
26
|
end
|
22
27
|
end
|
data/lib/timetrap/version.rb
CHANGED
data/lib/timetrap.rb
CHANGED
@@ -18,9 +18,12 @@ module Timetrap
|
|
18
18
|
DB_NAME = defined?(TEST_MODE) ? nil : Timetrap::Config['database_file']
|
19
19
|
# connect to database. This will create one if it doesn't exist
|
20
20
|
DB = Sequel.sqlite DB_NAME
|
21
|
-
|
21
|
+
# only declare cli options when run as standalone
|
22
|
+
if %w[dev_t t timetrap].include?(File.basename($PROGRAM_NAME)) || defined?(TEST_MODE)
|
23
|
+
CLI.args = Getopt::Declare.new(<<-EOF)
|
22
24
|
#{CLI::USAGE}
|
23
|
-
|
25
|
+
EOF
|
26
|
+
end
|
24
27
|
end
|
25
28
|
require File.expand_path(File.join(File.dirname(__FILE__), 'timetrap', 'schema'))
|
26
29
|
require File.expand_path(File.join(File.dirname(__FILE__), 'timetrap', 'models'))
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# Constants
|
2
|
+
TEST_MODE = true
|
3
|
+
|
4
|
+
# Vendors
|
5
|
+
require 'fakefs/safe'
|
6
|
+
|
7
|
+
# Load support files from the spec/support directory
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].sort.each { |f| require f }
|
9
|
+
|
10
|
+
# timetrap
|
11
|
+
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'timetrap'))
|
12
|
+
|
13
|
+
# Config
|
14
|
+
RSpec.configure do |config|
|
15
|
+
# Use color in STDOUT
|
16
|
+
config.color = true
|
17
|
+
# Use color not only in STDOUT but also in pagers and files
|
18
|
+
config.tty = true
|
19
|
+
|
20
|
+
# Display 10 slowest tests after a test run
|
21
|
+
config.profile_examples = false
|
22
|
+
|
23
|
+
# Use the specified formatter
|
24
|
+
# :documentation, :progress, :html, :json, CustomFormatterClass
|
25
|
+
config.formatter = :progress
|
26
|
+
|
27
|
+
# Specify order for spec to be run in
|
28
|
+
# TODO: make sure all specs pass when set to :rand
|
29
|
+
# config.order = :rand
|
30
|
+
|
31
|
+
# We are stubbing stderr and stdout, if you want to capture
|
32
|
+
# any of your output in tests, simply add :write_stdout_stderr => true
|
33
|
+
# as metadata to the end of your test
|
34
|
+
config.after(:each, write_stdout_stderr: true) do
|
35
|
+
$stderr.rewind
|
36
|
+
$stdout.rewind
|
37
|
+
File.write("stderr.txt", $stderr.read)
|
38
|
+
File.write("stdout.txt", $stdout.read)
|
39
|
+
end
|
40
|
+
end
|
data/spec/timetrap_spec.rb
CHANGED
@@ -1,43 +1,8 @@
|
|
1
|
-
TEST_MODE = true
|
2
|
-
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib', 'timetrap'))
|
3
|
-
require 'rspec'
|
4
|
-
require 'fakefs/safe'
|
5
|
-
|
6
|
-
RSpec.configure do |config|
|
7
|
-
# as we are stubbing stderr and stdout, if you want to capture
|
8
|
-
# any of your output in tests, simply add :write_stdout_stderr => true
|
9
|
-
# as metadata to the end of your test
|
10
|
-
config.after(:each, write_stdout_stderr: true) do
|
11
|
-
$stderr.rewind
|
12
|
-
$stdout.rewind
|
13
|
-
File.write("stderr.txt", $stderr.read)
|
14
|
-
File.write("stdout.txt", $stdout.read)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def local_time(str)
|
19
|
-
Timetrap::Timer.process_time(str)
|
20
|
-
end
|
21
|
-
|
22
|
-
def local_time_cli(str)
|
23
|
-
local_time(str).strftime('%Y-%m-%d %H:%M:%S')
|
24
|
-
end
|
25
|
-
|
26
|
-
module Timetrap::StubConfig
|
27
|
-
def with_stubbed_config options = {}
|
28
|
-
defaults = Timetrap::Config.defaults.dup
|
29
|
-
allow(Timetrap::Config).to receive(:[]) do |k|
|
30
|
-
defaults.merge(options)[k]
|
31
|
-
end
|
32
|
-
yield if block_given?
|
33
|
-
end
|
34
|
-
end
|
35
|
-
|
36
1
|
describe Timetrap do
|
37
|
-
include Timetrap::StubConfig
|
38
2
|
before do
|
39
3
|
with_stubbed_config
|
40
4
|
end
|
5
|
+
|
41
6
|
def create_entry atts = {}
|
42
7
|
Timetrap::Entry.create({
|
43
8
|
:sheet => 'default',
|
@@ -197,6 +162,16 @@ describe Timetrap do
|
|
197
162
|
expect(Timetrap::Timer.active_entry.note).to eq 'running entry//new//more'
|
198
163
|
end
|
199
164
|
|
165
|
+
it "should allow clearing the description of the active period" do
|
166
|
+
expect(Timetrap::Timer.active_entry.note).to eq 'running entry'
|
167
|
+
invoke 'edit --clear'
|
168
|
+
expect(Timetrap::Timer.active_entry.note).to eq ''
|
169
|
+
invoke 'edit running entry'
|
170
|
+
expect(Timetrap::Timer.active_entry.note).to eq 'running entry'
|
171
|
+
invoke 'edit -c'
|
172
|
+
expect(Timetrap::Timer.active_entry.note).to eq ''
|
173
|
+
end
|
174
|
+
|
200
175
|
it "should edit the start time of the active period" do
|
201
176
|
invoke 'edit --start "yesterday 10am"'
|
202
177
|
expect(Timetrap::Timer.active_entry.start).to eq Chronic.parse("yesterday 10am")
|
@@ -326,6 +301,20 @@ describe Timetrap do
|
|
326
301
|
expect(Timetrap::Timer.active_entry.note).to eq 'running entry//appended in editor'
|
327
302
|
end
|
328
303
|
end
|
304
|
+
|
305
|
+
context "clearing" do
|
306
|
+
it "should clear the last entry with -c" do
|
307
|
+
expect(Timetrap::Timer.active_entry.note).to eq 'running entry'
|
308
|
+
invoke "edit -c"
|
309
|
+
expect(Timetrap::Timer.active_entry.note).to eq ''
|
310
|
+
end
|
311
|
+
|
312
|
+
it "should clear the last entry with --clear" do
|
313
|
+
expect(Timetrap::Timer.active_entry.note).to eq 'running entry'
|
314
|
+
invoke "edit --clear"
|
315
|
+
expect(Timetrap::Timer.active_entry.note).to eq ''
|
316
|
+
end
|
317
|
+
end
|
329
318
|
end
|
330
319
|
end
|
331
320
|
|
@@ -721,11 +710,26 @@ start,end,note,sheet
|
|
721
710
|
"2008-10-05 12:00:00","2008-10-05 14:00:00","note","default"
|
722
711
|
EOF
|
723
712
|
end
|
713
|
+
|
714
|
+
it "should escape quoted notes" do
|
715
|
+
create_entry(
|
716
|
+
:start => local_time_cli('2008-10-07 12:00:00'),
|
717
|
+
:end => local_time_cli('2008-10-07 14:00:00'),
|
718
|
+
:note => %q{"note"}
|
719
|
+
)
|
720
|
+
invoke 'display --format csv'
|
721
|
+
expect($stdout.string).to eq <<-EOF
|
722
|
+
start,end,note,sheet
|
723
|
+
"2008-10-03 12:00:00","2008-10-03 14:00:00","note","default"
|
724
|
+
"2008-10-05 12:00:00","2008-10-05 14:00:00","note","default"
|
725
|
+
"2008-10-07 12:00:00","2008-10-07 14:00:00","""note""","default"
|
726
|
+
EOF
|
727
|
+
end
|
724
728
|
end
|
725
729
|
|
726
730
|
describe 'json' do
|
727
731
|
before do
|
728
|
-
create_entry(:start => local_time_cli('2008-10-03 12:
|
732
|
+
create_entry(:start => local_time_cli('2008-10-03 12:07:00'), :end => local_time_cli('2008-10-03 14:08:00'))
|
729
733
|
create_entry(:start => local_time_cli('2008-10-05 12:00:00'), :end => local_time_cli('2008-10-05 14:00:00'))
|
730
734
|
end
|
731
735
|
|
@@ -733,9 +737,21 @@ start,end,note,sheet
|
|
733
737
|
invoke 'in'
|
734
738
|
invoke 'display -f json'
|
735
739
|
expect(JSON.parse($stdout.string)).to eq JSON.parse(<<-EOF)
|
736
|
-
[{\"sheet\":\"default\",\"end\":\"#{local_time('2008-10-03 14:
|
740
|
+
[{\"sheet\":\"default\",\"end\":\"#{local_time('2008-10-03 14:08:00')}\",\"start\":\"#{local_time('2008-10-03 12:07:00')}\",\"note\":\"note\",\"id\":1},{\"sheet\":\"default\",\"end\":\"#{local_time('2008-10-05 14:00:00')}\",\"start\":\"#{local_time('2008-10-05 12:00:00')}\",\"note\":\"note\",\"id\":2}]
|
737
741
|
EOF
|
738
742
|
end
|
743
|
+
|
744
|
+
context 'with rounding on' do
|
745
|
+
it 'should export to json with rounded output' do
|
746
|
+
with_rounding_on do
|
747
|
+
# rounds to 900s by default
|
748
|
+
invoke 'display -r -f json'
|
749
|
+
expect(JSON.parse($stdout.string)).to eq JSON.parse(<<~EOF)
|
750
|
+
[{\"sheet\":\"default\",\"end\":\"#{local_time('2008-10-03 14:15:00')}\",\"start\":\"#{local_time('2008-10-03 12:00:00')}\",\"note\":\"note\",\"id\":1},{\"sheet\":\"default\",\"end\":\"#{local_time('2008-10-05 14:00:00')}\",\"start\":\"#{local_time('2008-10-05 12:00:00')}\",\"note\":\"note\",\"id\":2}]
|
751
|
+
EOF
|
752
|
+
end
|
753
|
+
end
|
754
|
+
end
|
739
755
|
end
|
740
756
|
|
741
757
|
describe 'ical' do
|
@@ -768,9 +784,8 @@ BEGIN:VCALENDAR
|
|
768
784
|
VERSION:2.0
|
769
785
|
CALSCALE:GREGORIAN
|
770
786
|
METHOD:PUBLISH
|
771
|
-
PRODID:
|
787
|
+
PRODID:icalendar-ruby
|
772
788
|
BEGIN:VEVENT
|
773
|
-
SEQUENCE:0
|
774
789
|
DTEND:20081003T140000
|
775
790
|
SUMMARY:note
|
776
791
|
DTSTART:20081003T120000
|
@@ -1500,11 +1515,19 @@ END:VCALENDAR
|
|
1500
1515
|
end
|
1501
1516
|
|
1502
1517
|
it "should note if the user is already on that sheet" do
|
1518
|
+
create_entry(sheet: "sheet 1")
|
1503
1519
|
invoke 'sheet sheet 1'
|
1504
1520
|
invoke 'sheet sheet 1'
|
1505
1521
|
expect($stderr.string).to eq "Switching to sheet \"sheet 1\"\nAlready on sheet \"sheet 1\"\n"
|
1506
1522
|
end
|
1507
1523
|
|
1524
|
+
it "should indicate when switching to a new sheet" do
|
1525
|
+
create_entry(sheet: "foo")
|
1526
|
+
invoke 'sheet foo'
|
1527
|
+
invoke 'sheet bar'
|
1528
|
+
expect($stderr.string).to eq "Switching to sheet \"foo\"\nSwitching to sheet \"bar\" (new sheet)\n"
|
1529
|
+
end
|
1530
|
+
|
1508
1531
|
describe "using - to switch to the last sheet" do
|
1509
1532
|
it "should warn if there isn't a sheet set" do
|
1510
1533
|
expect(lambda do
|
@@ -1634,7 +1657,6 @@ END:VCALENDAR
|
|
1634
1657
|
|
1635
1658
|
describe Timetrap::Entry do
|
1636
1659
|
|
1637
|
-
include Timetrap::StubConfig
|
1638
1660
|
describe "with an instance" do
|
1639
1661
|
before do
|
1640
1662
|
@time = Time.now
|
@@ -1675,16 +1697,6 @@ END:VCALENDAR
|
|
1675
1697
|
expect(@entry.sheet).to eq 'name'
|
1676
1698
|
end
|
1677
1699
|
|
1678
|
-
def with_rounding_on
|
1679
|
-
old_val = Timetrap::Entry.round
|
1680
|
-
begin
|
1681
|
-
Timetrap::Entry.round = true
|
1682
|
-
block_return_value = yield
|
1683
|
-
ensure
|
1684
|
-
Timetrap::Entry.round = old_val
|
1685
|
-
end
|
1686
|
-
end
|
1687
|
-
|
1688
1700
|
it "should use round start if the global round attribute is set" do
|
1689
1701
|
with_rounding_on do
|
1690
1702
|
with_stubbed_config('round_in_seconds' => 900) do
|
data/timetrap.gemspec
CHANGED
@@ -23,10 +23,10 @@ Gem::Specification.new do |spec|
|
|
23
23
|
spec.add_development_dependency "rspec", "~> 3.9.0"
|
24
24
|
spec.add_development_dependency "fakefs", "~> 0.20"
|
25
25
|
# More recent versions of icalendar drop support for Ruby 1.8.7
|
26
|
-
spec.add_development_dependency "icalendar", "~>
|
26
|
+
spec.add_development_dependency "icalendar", "~> 2.7"
|
27
27
|
spec.add_development_dependency "json", "~> 2.3"
|
28
|
-
spec.add_dependency "sequel", "~> 5.
|
29
|
-
spec.add_dependency "sqlite3", "~> 1.4
|
28
|
+
spec.add_dependency "sequel", "~> 5.90.0"
|
29
|
+
spec.add_dependency "sqlite3", "~> 1.4"
|
30
30
|
|
31
31
|
spec.add_dependency "chronic", "~> 0.10.2"
|
32
32
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: timetrap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.15.
|
4
|
+
version: 1.15.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Goldstein
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2025-03-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -72,14 +72,14 @@ dependencies:
|
|
72
72
|
requirements:
|
73
73
|
- - "~>"
|
74
74
|
- !ruby/object:Gem::Version
|
75
|
-
version:
|
75
|
+
version: '2.7'
|
76
76
|
type: :development
|
77
77
|
prerelease: false
|
78
78
|
version_requirements: !ruby/object:Gem::Requirement
|
79
79
|
requirements:
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
|
-
version:
|
82
|
+
version: '2.7'
|
83
83
|
- !ruby/object:Gem::Dependency
|
84
84
|
name: json
|
85
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,28 +100,28 @@ dependencies:
|
|
100
100
|
requirements:
|
101
101
|
- - "~>"
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version: 5.
|
103
|
+
version: 5.90.0
|
104
104
|
type: :runtime
|
105
105
|
prerelease: false
|
106
106
|
version_requirements: !ruby/object:Gem::Requirement
|
107
107
|
requirements:
|
108
108
|
- - "~>"
|
109
109
|
- !ruby/object:Gem::Version
|
110
|
-
version: 5.
|
110
|
+
version: 5.90.0
|
111
111
|
- !ruby/object:Gem::Dependency
|
112
112
|
name: sqlite3
|
113
113
|
requirement: !ruby/object:Gem::Requirement
|
114
114
|
requirements:
|
115
115
|
- - "~>"
|
116
116
|
- !ruby/object:Gem::Version
|
117
|
-
version: 1.4
|
117
|
+
version: '1.4'
|
118
118
|
type: :runtime
|
119
119
|
prerelease: false
|
120
120
|
version_requirements: !ruby/object:Gem::Requirement
|
121
121
|
requirements:
|
122
122
|
- - "~>"
|
123
123
|
- !ruby/object:Gem::Version
|
124
|
-
version: 1.4
|
124
|
+
version: '1.4'
|
125
125
|
- !ruby/object:Gem::Dependency
|
126
126
|
name: chronic
|
127
127
|
requirement: !ruby/object:Gem::Requirement
|
@@ -147,6 +147,8 @@ executables:
|
|
147
147
|
extensions: []
|
148
148
|
extra_rdoc_files: []
|
149
149
|
files:
|
150
|
+
- ".github/pull_request_template.md"
|
151
|
+
- ".github/workflows/rspec.yml"
|
150
152
|
- ".gitignore"
|
151
153
|
- ".rspec"
|
152
154
|
- ".travis.yml"
|
@@ -184,6 +186,10 @@ files:
|
|
184
186
|
- spec/dotfile/.timetrap-sheet
|
185
187
|
- spec/dotfile/nested/.timetrap-sheet
|
186
188
|
- spec/dotfile/nested/no-sheet/.gitkeep
|
189
|
+
- spec/spec_helper.rb
|
190
|
+
- spec/support/local_time.rb
|
191
|
+
- spec/support/with_rounding_on.rb
|
192
|
+
- spec/support/with_stubbed_config.rb
|
187
193
|
- spec/timetrap_spec.rb
|
188
194
|
- timetrap-1.14.3.gem
|
189
195
|
- timetrap.gemspec
|
@@ -191,7 +197,7 @@ homepage: https://github.com/samg/timetrap
|
|
191
197
|
licenses:
|
192
198
|
- MIT
|
193
199
|
metadata: {}
|
194
|
-
post_install_message:
|
200
|
+
post_install_message:
|
195
201
|
rdoc_options: []
|
196
202
|
require_paths:
|
197
203
|
- lib
|
@@ -206,12 +212,16 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
206
212
|
- !ruby/object:Gem::Version
|
207
213
|
version: '0'
|
208
214
|
requirements: []
|
209
|
-
rubygems_version: 3.
|
210
|
-
signing_key:
|
215
|
+
rubygems_version: 3.5.11
|
216
|
+
signing_key:
|
211
217
|
specification_version: 4
|
212
218
|
summary: Command line time tracker
|
213
219
|
test_files:
|
214
220
|
- spec/dotfile/.timetrap-sheet
|
215
221
|
- spec/dotfile/nested/.timetrap-sheet
|
216
222
|
- spec/dotfile/nested/no-sheet/.gitkeep
|
223
|
+
- spec/spec_helper.rb
|
224
|
+
- spec/support/local_time.rb
|
225
|
+
- spec/support/with_rounding_on.rb
|
226
|
+
- spec/support/with_stubbed_config.rb
|
217
227
|
- spec/timetrap_spec.rb
|