Skip to content

Commit

Permalink
Enable dsu add --date to accept relative date mnemonics
Browse files Browse the repository at this point in the history
  • Loading branch information
gangelo committed Feb 8, 2024
1 parent f6e5885 commit c7a37d2
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ All notable changes to this project will be documented in this file.

### Enhancements
[x] Added `dsu project` command to manage DSU projects. See `dsu help project` or the [dsu wiki](https://github.com/gangelo/dsu/wiki) for more information.
[x] The `dsu add` command how allows you to add entries using mnemonics and relative date mnemonics (RDMs) in addition to absolute dates. For example, `dsu add -d -7 "My entry"` will add an entry one week in the past from the current day. See `dsu help add` for more information.

### Changes
[x] Update ruby gems.
Expand Down
22 changes: 17 additions & 5 deletions lib/dsu/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@
require_relative 'subcommands/list'
require_relative 'subcommands/project'
require_relative 'subcommands/theme'
require_relative 'support/command_options/time_mnemonic'
require_relative 'support/time_formatable'
require_relative 'views/entry_group/list'

module Dsu
# The `dsu` command.
class CLI < BaseCLI
include Support::CommandOptions::TimeMnemonic
include Support::TimeFormatable

map I18n.t('commands.add.key_mappings') => :add
map I18n.t('commands.browse.key_mappings') => :browse
map I18n.t('commands.config.key_mappings') => :config
Expand All @@ -39,20 +44,27 @@ class CLI < BaseCLI
option I18n.t('options.yesterday.name'), aliases: I18n.t('options.yesterday.aliases'), type: :boolean
option I18n.t('options.today.name'), aliases: I18n.t('options.today.aliases'), type: :boolean, default: true
def add(description)
time = if options[I18n.t('options.date.name')].present?
Time.parse(options[I18n.t('options.date.name')])
date_or_mnemonic = if options[I18n.t('options.date.name')].present?
options[I18n.t('options.date.name')]
elsif options[I18n.t('options.tomorrow.name')].present?
Time.now.tomorrow
I18n.t('options.tomorrow.name')
elsif options[I18n.t('options.yesterday.name')].present?
Time.now.yesterday
I18n.t('options.yesterday.name')
elsif options[I18n.t('options.today.name')].present?
Time.now
I18n.t('options.today.name')
end
time = if time_mnemonic?(date_or_mnemonic)
time_from_mnemonic(command_option: date_or_mnemonic)
else
Time.parse(date_or_mnemonic)
end
entry = Models::Entry.new(description: description)
CommandServices::AddEntryService.new(entry: entry, time: time).call
presenter = Presenters::EntryGroup::List::DatePresenter.new(times: [time], options: options)
# TODO: Refactor View::EntryGroup::Show to accept a presenter and use it here
Views::EntryGroup::List.new(presenter: presenter).render
rescue ArgumentError => e
Views::Shared::Error.new(messages: e.message).render
end

desc I18n.t('commands.browse.desc'), I18n.t('commands.browse.usage')
Expand Down
90 changes: 62 additions & 28 deletions spec/dsu/features/dsu_add_features_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

RSpec.describe 'Dsu add features', type: :feature do
subject(:cli) do
strip_escapes(Dsu::Services::StdoutRedirectorService.call { Dsu::CLI.start(args) })
capture_stdout_and_strip_escapes { Dsu::CLI.start(args) }
end

let(:args) { %w[add] }
Expand Down Expand Up @@ -43,24 +43,25 @@
end
end

context "when 'dsu add --date=DATE' is called" do
context "when 'dsu add --tomorrow' is called" do
before do
with_entries

freeze_time_at(time_string: '2023-06-16')
end

let(:args) { ['add', '--date', entry_date, entry_description] }
let(:entry_date) { '2023-06-16' }
let(:args) { ['add', '--tomorrow', entry_description] }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.parse(entry_date))
Dsu::Support::TimeFormatable.formatted_time(time: Time.now.tomorrow)
end

it 'displays the entry group date' do
expect(cli).to include(expected_date)
end

it 'displays the entries already existing in the group' do
expected_entry_descriptions = ['20230616 description 0', '20230616 description 1']
expected_entry_descriptions = ['20230617 description 0', '20230617 description 1']
expected_entry_descriptions.each do |entry_description|
expect(cli).to include(entry_description)
end
Expand All @@ -71,25 +72,25 @@
end
end

context "when 'dsu add --tomorrow' is called" do
context "when 'dsu add --yesterday' is called" do
before do
with_entries

freeze_time_at(time_string: '2023-06-16')
end

let(:args) { ['add', '--tomorrow', entry_description] }
let(:args) { ['add', '--yesterday', entry_description] }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.now.tomorrow)
Dsu::Support::TimeFormatable.formatted_time(time: Time.now.yesterday)
end

it 'displays the entry group date' do
expect(cli).to include(expected_date)
end

it 'displays the entries already existing in the group' do
expected_entry_descriptions = ['20230617 description 0', '20230617 description 1']
expected_entry_descriptions = ['20230615 description 0', '20230615 description 1']
expected_entry_descriptions.each do |entry_description|
expect(cli).to include(entry_description)
end
Expand All @@ -100,25 +101,25 @@
end
end

context "when 'dsu add --yesterday' is called" do
context "when 'dsu add --today' is called" do
before do
with_entries

freeze_time_at(time_string: '2023-06-16')
end

let(:args) { ['add', '--yesterday', entry_description] }
let(:args) { ['add', '--today', entry_description] }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.now.yesterday)
Dsu::Support::TimeFormatable.formatted_time(time: Time.now)
end

it 'displays the entry group date' do
expect(cli).to include(expected_date)
end

it 'displays the entries already existing in the group' do
expected_entry_descriptions = ['20230615 description 0', '20230615 description 1']
expected_entry_descriptions = ['20230616 description 0', '20230616 description 1']
expected_entry_descriptions.each do |entry_description|
expect(cli).to include(entry_description)
end
Expand All @@ -129,32 +130,65 @@
end
end

context "when 'dsu add --today' is called" do
context "when 'dsu add --date=DATE' is called" do
before do
with_entries
end

freeze_time_at(time_string: '2023-06-16')
shared_examples 'the expected output is displayed' do
it 'displays the expected output' do
expect(cli.split("\n")[0..4].map(&:squish).reject(&:blank?)).to eq(expected_output.split("\n"))
end
end

let(:args) { ['add', '--today', entry_description] }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.now)
let(:expected_output) do
<<~OUTPUT
#{expected_date}
1. #{entry_date.tr('-', '')} description 0
2. #{entry_date.tr('-', '')} description 1
3. #{entry_description}
OUTPUT
end

it 'displays the entry group date' do
expect(cli).to include(expected_date)
context 'when using option --date' do
let(:args) { ['add', '--date', entry_date, entry_description] }
let(:entry_date) { '2023-06-16' }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.parse(entry_date))
end

it_behaves_like 'the expected output is displayed'
end

it 'displays the entries already existing in the group' do
expected_entry_descriptions = ['20230616 description 0', '20230616 description 1']
expected_entry_descriptions.each do |entry_description|
expect(cli).to include(entry_description)
context 'when using --date with a positive relative date mnemonic' do
before do
freeze_time_at(time_string: '2023-06-16')
end

let(:args) { ['add', '--date', '+1', entry_description] }
let(:entry_date) { '2023-06-17' }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.parse(entry_date))
end

it_behaves_like 'the expected output is displayed'
end

it 'displays the description that was added' do
expect(cli).to include(entry_description)
context 'when using --date with a negative relative date mnemonic' do
before do
freeze_time_at(time_string: '2023-06-16')
end

let(:args) { ['add', '--date', '-1', entry_description] }
let(:entry_date) { '2023-06-15' }
let(:entry_description) { 'This is a test' }
let(:expected_date) do
Dsu::Support::TimeFormatable.formatted_time(time: Time.parse(entry_date))
end

it_behaves_like 'the expected output is displayed'
end
end
end

0 comments on commit c7a37d2

Please sign in to comment.