From 5562e805e667dbc48ad4c8a64b8b27be8f2e5329 Mon Sep 17 00:00:00 2001 From: Philipp Staender Date: Sun, 10 Sep 2023 09:25:00 +0200 Subject: [PATCH] do not store redundant titles; renames specs titles --- .rspec | 2 ++ lib/punchcard.rb | 25 +++++++++++++------------ spec/punchcard_spec.rb | 39 ++++++++++++++++++++++++--------------- 3 files changed, 39 insertions(+), 27 deletions(-) create mode 100644 .rspec diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..16f9cdb --- /dev/null +++ b/.rspec @@ -0,0 +1,2 @@ +--color +--format documentation diff --git a/lib/punchcard.rb b/lib/punchcard.rb index 833cf45..1f03a87 100755 --- a/lib/punchcard.rb +++ b/lib/punchcard.rb @@ -13,7 +13,7 @@ class PunchCard HOURLY_RATE_PATTERN = /^\s*(\d+)([^\d]+)*\s*/i.freeze TIME_POINT_PATTERN = /^((\d+|.+?\s[\+\-]\d{4}?\s*)(\-)*(\d+|\s.+\d?)*)$/.freeze META_KEY_PATTERN = /^([a-zA-Z0-9]+)\:\s*(.*)$/.freeze - VERSION = '1.3.3' + VERSION = '1.4.0' attr_accessor :title @@ -149,7 +149,7 @@ def rename(new_project_name) old_filename = project_filename data = project_data data[0] = new_project_name - write_string_to_project_file! data.join("\n") + write_string_to_project_file! data.join("\n").chomp self.project = new_project_name File.rename(old_filename, project_filename) && "#{old_filename} -> #{project_filename}" end @@ -272,7 +272,7 @@ def end_time end def time_points - line_to_time_points last_entry + line_to_time_points(last_entry) if last_entry end def line_to_time_points(line) @@ -290,10 +290,7 @@ def string_to_timestamp(str) return str if str.nil? str.strip! - # here some legacy… previous versions stored timestamp, - # but now punched stores date-time strings for better readability. - # So we have to convert timestamp and date-time format into timestamp - str =~ /^\d+$/ ? str.to_i : (str =~ /^\d{4}\-\d/ ? Time.parse(str).to_i : nil) + str =~ /^\d{4}\-\d/ ? Time.parse(str).to_i : nil end def last_entry @@ -316,7 +313,7 @@ def read_project_data line.strip! next if line.start_with?('#') - if i.zero? && !line.match(TIME_POINT_PATTERN) + if i.zero? && !line.empty? && !line.match(TIME_POINT_PATTERN) title = line elsif line.match(META_KEY_PATTERN) set line.match(META_KEY_PATTERN)[1], line.match(META_KEY_PATTERN)[2] @@ -339,17 +336,17 @@ def project_data_without_comments end def write_string_to_project_file!(string) - File.open(project_file, 'w') { |f| f.write(string) } + File.write(project_file, string ? string.chomp : '') end def write_to_project_file! timestamps = project_data.select { |line| line.match(TIME_POINT_PATTERN) } meta_data_lines = @meta_data.map { |key, value| "#{key}: #{value}" } - write_string_to_project_file! [@project, meta_data_lines.join("\n"), timestamps].reject(&:empty?).join("\n") + write_string_to_project_file! [project_name_if_differs_from_filename || '', meta_data_lines.join("\n"), timestamps].reject(&:empty?).join("\n") end def append_new_line(line) - open(project_file, 'a') { |f| f.puts("\n" + line.to_s.strip) } + File.open(project_file, 'a') { |f| f.puts("\n#{line.to_s.strip}") } end def replace_last_line(line) @@ -371,10 +368,14 @@ def project_exist? end def find_or_make_file - write_string_to_project_file!(@project + "\n") unless project_exist? + write_string_to_project_file!(project_name_if_differs_from_filename) unless project_exist? self.title ||= project_data.first end + def project_name_if_differs_from_filename + @project != File.basename(project_file) ? @project : nil + end + def find_or_make_settings_dir Dir.mkdir(SETTINGS_DIR) unless File.exist?(SETTINGS_DIR) end diff --git a/spec/punchcard_spec.rb b/spec/punchcard_spec.rb index 194881a..4a1a04c 100644 --- a/spec/punchcard_spec.rb +++ b/spec/punchcard_spec.rb @@ -46,25 +46,25 @@ def two_seconds_tracking example_project end - it 'should create a new PunchCard object' do + it 'creates a new project / PunchCard object' do expect(example_project).to be_a(PunchCard) end - it 'should start a project' do + it 'starts a project' do example_project.start end - it 'should start and stop a project' do + it 'starts and stops a project' do start_and_stop end - it 'should track a project time' do + it 'tracks project time' do start_and_stop expect(my_project_file.lines.first.strip).to eq('My Project') expect(my_project_file.lines.last.strip).to match(/^\d+-\d+-\d+ .+? - \d+-\d+-\d+ /) end - it 'should calculate tracked total time' do + it 'calculates tracked total time' do project = two_seconds_tracking tracked_time = project.details.lines.last.match(/^\d{2}\:\d{2}\:(\d{2}).*total/)[1].to_i expect(tracked_time).to be_between 1, 3 @@ -73,7 +73,7 @@ def two_seconds_tracking expect(tracked_time).to be_between 3, 5 end - it 'should toggle' do + it 'toggles project status (start + stop)' do project = start_and_stop expect(project.status.lines.first).to match /stopped/ project.toggle @@ -91,20 +91,20 @@ def two_seconds_tracking expect(my_project_file).to match("\n# A comment line") end - it 'should convert names to underscore with special characters' do + it 'converts names to underscore with special characters' do PunchCard.new 'Playing Motörhead' expect(my_project_file('playing_mot_rhead').strip).to eq('Playing Motörhead') project = PunchCard.new 'Playing*' expect(project.project).to eq('playing_mot_rhead') end - it 'should set hourlyRate' do + it 'sets hourlyRate' do project = start_and_stop project.set 'hourlyRate', '1000 €' - expect(my_project_file.lines[1].strip).to eq('hourlyRate: 1000 €') + expect(my_project_file.lines.first.chomp).to eq('hourlyRate: 1000 €') end - it 'should calculate earnings' do + it 'calculates earnings' do project = start_and_stop project.set 'hourlyRate', '1000EURO' project.toggle @@ -116,7 +116,7 @@ def two_seconds_tracking expect(project.csv).to match /^"My Project \[my_project\]","stopped","[0-9\-\s\:]+?","[0-9\:]+?","1000.0 EURO","1\.\d+ EURO"$/ end - it 'should track different projects simultanously' do + it 'tracks different projects simultanously' do project_a = random_project project_b = random_project expect(project_a.project).not_to eq(project_b.project) @@ -129,7 +129,16 @@ def two_seconds_tracking expect(project_b.total.to_i - project_a.total.to_i).to be_between(2, 4) end - it 'should load latest project by wildcard' do + it 'stores title correctly if differs from filename' do + project = random_project + project.start + sleep 2 + project.stop + project = random_project + expect(project.title).to start_with('My random Project ') + end + + it 'loads latest project by wildcard' do project_a = random_project project = PunchCard.new 'My random*' expect(project.project).to eq(project_a.project) @@ -140,7 +149,7 @@ def two_seconds_tracking expect(project.project).not_to eq(project_a.project) end - it 'should rename' do + it 'renames project' do project = example_project content = my_project_file project.rename 'Renamed Project' @@ -156,14 +165,14 @@ def two_seconds_tracking expect(File.exist?("#{example_settings_dir}/renamed_project")).to be_falsey end - it 'should remove' do + it 'removes project' do project = example_project expect(File.exist?("#{example_settings_dir}/my_project")).to be_truthy project.remove expect(File.exist?("#{example_settings_dir}/my_project")).to be_falsey end - it 'should call punched all' do + it 'show all projects' do two_seconds_tracking result = `#{punched_bin} all` expect(result).to match('My Project')