tamarillo 0.1.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.
Files changed (43) hide show
  1. data/.gitignore +19 -0
  2. data/.travis.yml +6 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +22 -0
  5. data/README.md +83 -0
  6. data/Rakefile +23 -0
  7. data/bin/tam +4 -0
  8. data/features/config.feature +44 -0
  9. data/features/step_definitions/tamarillo_steps.rb +50 -0
  10. data/features/support/env.rb +5 -0
  11. data/features/tamarillo.feature +47 -0
  12. data/lib/tamarillo/clock.rb +33 -0
  13. data/lib/tamarillo/command.rb +68 -0
  14. data/lib/tamarillo/config.rb +95 -0
  15. data/lib/tamarillo/controller.rb +113 -0
  16. data/lib/tamarillo/monitor.rb +27 -0
  17. data/lib/tamarillo/notification/bell.rb +15 -0
  18. data/lib/tamarillo/notification/growl.rb +13 -0
  19. data/lib/tamarillo/notification/none.rb +13 -0
  20. data/lib/tamarillo/notification/speech.rb +13 -0
  21. data/lib/tamarillo/notification/touch.rb +16 -0
  22. data/lib/tamarillo/notification.rb +36 -0
  23. data/lib/tamarillo/storage.rb +118 -0
  24. data/lib/tamarillo/tomato.rb +96 -0
  25. data/lib/tamarillo/tomato_file.rb +60 -0
  26. data/lib/tamarillo/version.rb +3 -0
  27. data/lib/tamarillo.rb +7 -0
  28. data/spec/lib/tamarillo/clock_spec.rb +39 -0
  29. data/spec/lib/tamarillo/command_spec.rb +17 -0
  30. data/spec/lib/tamarillo/config_spec.rb +133 -0
  31. data/spec/lib/tamarillo/controller_spec.rb +137 -0
  32. data/spec/lib/tamarillo/monitor_spec.rb +27 -0
  33. data/spec/lib/tamarillo/notification/bell_spec.rb +7 -0
  34. data/spec/lib/tamarillo/notification/growl_spec.rb +7 -0
  35. data/spec/lib/tamarillo/notification/speech_spec.rb +7 -0
  36. data/spec/lib/tamarillo/notification_spec.rb +22 -0
  37. data/spec/lib/tamarillo/storage_spec.rb +171 -0
  38. data/spec/lib/tamarillo/tomato_file_spec.rb +41 -0
  39. data/spec/lib/tamarillo/tomato_spec.rb +116 -0
  40. data/spec/support/invalid-config.yml +1 -0
  41. data/spec/support/sample-config.yml +3 -0
  42. data/tamarillo.gemspec +26 -0
  43. metadata +178 -0
@@ -0,0 +1,27 @@
1
+ require_relative '../../../lib/tamarillo/monitor'
2
+
3
+ describe Tamarillo::Monitor do
4
+ let(:tomato) do
5
+ tomato = double('tomato')
6
+ tomato.stub(:completed?).and_return(false, true)
7
+ tomato
8
+ end
9
+
10
+ let(:notifier) do
11
+ notifier = double('notifier')
12
+ notifier.should_receive(:call)
13
+ notifier
14
+ end
15
+
16
+ # XXX This test relies on system time passing,
17
+ # so it's unfortunately slow.
18
+ subject { Tamarillo::Monitor.new(tomato, notifier) }
19
+
20
+ # as a result it is horrible.
21
+ it "watches a tomato for completion" do
22
+ pending "not sure how to test when forking"
23
+ subject.start
24
+ sleep 0.1
25
+ end
26
+ end
27
+
@@ -0,0 +1,7 @@
1
+ require_relative '../../../../lib/tamarillo/notification/bell'
2
+
3
+ describe Tamarillo::Notification::Bell do
4
+ subject { Tamarillo::Notification::Bell.new }
5
+ it { should respond_to(:call) }
6
+ # specify { subject.call }
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../../../../lib/tamarillo/notification/growl'
2
+
3
+ describe Tamarillo::Notification::Growl do
4
+ subject { Tamarillo::Notification::Growl.new }
5
+ it { should respond_to(:call) }
6
+ # specify { subject.call }
7
+ end
@@ -0,0 +1,7 @@
1
+ require_relative '../../../../lib/tamarillo/notification/speech'
2
+
3
+ describe Tamarillo::Notification::Speech do
4
+ subject { Tamarillo::Notification::Speech.new }
5
+ it { should respond_to(:call) }
6
+ # specify { subject.call }
7
+ end
@@ -0,0 +1,22 @@
1
+ require_relative '../../../lib/tamarillo/notification'
2
+
3
+ include Tamarillo
4
+
5
+ describe Tamarillo::Notification do
6
+ subject { Tamarillo::Notification }
7
+
8
+ describe ".valid!" do
9
+ specify { subject.valid!(:bell).should == Notification::BELL }
10
+ specify { subject.valid!('speech').should == Notification::SPEECH }
11
+ specify { subject.valid!('Growl').should == Notification::GROWL }
12
+ specify { subject.valid!('bogus').should == nil }
13
+ end
14
+
15
+ describe ".for" do
16
+ specify { subject.for(Notification::BELL).should be_a(Notification::Bell) }
17
+ specify { subject.for(Notification::GROWL).should be_a(Notification::Growl) }
18
+ specify { subject.for(Notification::SPEECH).should be_a(Notification::Speech) }
19
+ specify { subject.for(Notification::NONE).should be_a(Notification::None) }
20
+ specify { subject.for('bogus').should be_a(Notification::None) }
21
+ end
22
+ end
@@ -0,0 +1,171 @@
1
+ require_relative '../../../lib/tamarillo/storage'
2
+ require 'fakefs/spec_helpers'
3
+ require 'active_support/core_ext/numeric/time'
4
+
5
+ include Tamarillo
6
+
7
+ # Storage layout looks like this
8
+ # |,tamarillo
9
+ # |-config
10
+ # |-basket.sqlite
11
+ # |-basket
12
+ # |-2012
13
+ # |-0401
14
+ # |-060101
15
+
16
+ describe Storage do
17
+ include FakeFS::SpecHelpers
18
+
19
+ let(:time) { Time.local(2011,1,1,6,0,0) }
20
+ let(:date) { Date.new(2011,1,1) }
21
+ let(:storage_path) { Pathname.new( File.expand_path('tmp/tamarillo')) }
22
+ let(:config_path) { storage_path.join('config.yml') }
23
+ let(:tomato_path) { storage_path.join('2011/0101/20110101060000') }
24
+ let(:sample_tomato) { <<EOS }
25
+ #{time.iso8601}
26
+ Some task I'm working on
27
+ completed
28
+ EOS
29
+
30
+ def create_tomato_file(time, options = {})
31
+ folder_path = storage_path.join(time.strftime('%Y/%m%d'))
32
+ tomato_path = folder_path.join(time.strftime('%Y%m%d%H%M%S'))
33
+ state = options.fetch(:state) { 'completed' }
34
+
35
+ FileUtils.mkdir_p(folder_path)
36
+ File.open(tomato_path, 'w') { |f| f << <<EOS }
37
+ #{time.iso8601}
38
+ Some task I'm working on
39
+ #{state}
40
+ EOS
41
+
42
+ tomato_path
43
+ end
44
+
45
+
46
+ subject { Storage.new(storage_path) }
47
+
48
+ it "creates the storage directory if it is missing" do
49
+ expect { Storage.new(storage_path) }.
50
+ to change { File.directory?(storage_path) }
51
+ end
52
+
53
+ it "has a path to the storage directory" do
54
+ subject.path.should == storage_path
55
+ end
56
+
57
+ it "has a default configuration" do
58
+ subject.config.should be_a(Tamarillo::Config)
59
+ end
60
+
61
+ it "can accept a specific configuration" do
62
+ config = stub(:duration => 10)
63
+ storage = Storage.new(storage_path, config)
64
+ storage.config.duration.should == 10
65
+ end
66
+
67
+ describe "writing config to the filesystem" do
68
+ it "writes files to the right place" do
69
+ FakeFS::FileSystem.clear
70
+ FakeFS do
71
+ expect { subject.write_config }.
72
+ to change { File.exist?(config_path) }
73
+ end
74
+ end
75
+ end
76
+
77
+ describe "reading config from the filesystem" do
78
+ end
79
+
80
+ describe "reading monitor from the filesystem" do
81
+ end
82
+
83
+ describe "writing tomatoes to the filesystem" do
84
+ it "writes files to the right place" do
85
+ FakeFS::FileSystem.clear
86
+ FakeFS do
87
+ tomato = stub(:started_at => time, :state => :active)
88
+ expect { subject.write_tomato(tomato) }.
89
+ to change { File.exist?(tomato_path) }
90
+ end
91
+ end
92
+
93
+ it "returns a path to the tomato" do
94
+ tomato = stub(:started_at => time, :state => :active)
95
+ path = subject.write_tomato(tomato)
96
+ path.should == subject.path.join(tomato_path)
97
+ end
98
+
99
+ describe "tomato file" do
100
+ before do
101
+ tomato = stub(:started_at => time, :date => date, :state => :active)
102
+ Storage.new(storage_path).write_tomato(tomato)
103
+ end
104
+
105
+ subject { FakeFS { File.readlines(tomato_path.to_s) } }
106
+
107
+ specify { subject[0].should == time.iso8601}
108
+ specify { subject[1].should == "Some task I'm working on" }
109
+ specify { subject[2].should == 'active' }
110
+ end
111
+ end
112
+
113
+ describe "reading tomatoes from the filesystem" do
114
+ before do
115
+ create_tomato_file(time)
116
+ end
117
+
118
+ it "can read tomatoes from the filesystem" do
119
+ tomato = subject.read_tomato(tomato_path)
120
+ tomato.should be
121
+ end
122
+
123
+ it "returns nil of not found" do
124
+ tomato = subject.read_tomato('NOTHING')
125
+ tomato.should be_nil
126
+ end
127
+
128
+ describe "the tomato" do
129
+ let(:config) { stub(:duration_in_seconds => 10.minutes) }
130
+ let(:storage) { Storage.new(storage_path, config) }
131
+ subject { storage.read_tomato(tomato_path) }
132
+
133
+ its(:started_at) { should == time }
134
+ its(:date) { should == date }
135
+ its(:duration) { should == 10.minutes }
136
+ it { should be_completed }
137
+ end
138
+
139
+ it "handles interrupted tomatoes" do
140
+ create_tomato_file(time, :state => 'interrupted')
141
+ tomato = subject.read_tomato(tomato_path)
142
+ tomato.should be_interrupted
143
+ end
144
+ end
145
+
146
+ describe "finding most recent tomato" do
147
+ subject { Storage.new(storage_path).latest }
148
+
149
+ context "when there are many tomatoes" do
150
+ before do
151
+ create_tomato_file(Date.today.to_time + 6.hours)
152
+ create_tomato_file(Date.today.to_time + 6.hours + 15.minutes)
153
+ end
154
+
155
+ its(:started_at) { should == Date.today.to_time + 6.hours + 15.minutes }
156
+ end
157
+
158
+ context "when there are no tomatoes for the day" do
159
+ before do
160
+ create_tomato_file(Date.today.to_time - 1.days)
161
+ end
162
+
163
+ it { should be_nil }
164
+ end
165
+ end
166
+
167
+ # it "can count how many tomatoes are stored"
168
+ # it "can find tomatoes by week"
169
+ # it "can find tomatoes by month"
170
+ # something can group them by day and maybe task
171
+ end
@@ -0,0 +1,41 @@
1
+ require_relative '../../../lib/tamarillo/tomato_file'
2
+ require_relative '../../../lib/tamarillo/tomato'
3
+ require_relative '../../../lib/tamarillo/clock'
4
+
5
+ describe Tamarillo::TomatoFile do
6
+ # FIXME Timezones will change when running test, argh
7
+ let(:time) { Time.local(2011,1,1, 6,0,0) }
8
+ let(:today) { Date.new(2011,1,1) }
9
+ let(:clock) { Tamarillo::Clock.new(time) }
10
+ let(:tomato) { Tamarillo::Tomato.new(25 * 60, clock) }
11
+
12
+ subject { Tamarillo::TomatoFile.new(tomato) }
13
+
14
+ its(:name) { should == '20110101060000' }
15
+ its(:path) { should == '2011/0101/20110101060000' }
16
+ its(:content) { should == <<-EOS.chomp }
17
+ #{time.iso8601}
18
+ Some task I'm working on
19
+ completed
20
+ EOS
21
+
22
+ it "can write an interrupted tomato" do
23
+ tomato.interrupt!
24
+ subject.content.should include('interrupted')
25
+ end
26
+
27
+ describe ".path" do
28
+ subject { Tamarillo::TomatoFile }
29
+
30
+ specify do
31
+ path = subject.path(Time.new(1999,12,31,11,59,59))
32
+ path.should == '1999/1231/19991231115959'
33
+ end
34
+
35
+ specify do
36
+ path = subject.path(Time.new(2012,04,10,6,0,23))
37
+ path.should == '2012/0410/20120410060023'
38
+ end
39
+ end
40
+
41
+ end
@@ -0,0 +1,116 @@
1
+ require 'active_support/core_ext/numeric/time'
2
+ require_relative '../../../lib/tamarillo/tomato'
3
+
4
+ include Tamarillo
5
+
6
+ describe Tomato do
7
+ subject { Tomato.new(25.minutes, clock) }
8
+
9
+ describe "basic attibutes" do
10
+ let(:now) { Time.new(2012,1,1,6,0,0) }
11
+ let(:today) { Date.new(2012,1,1) }
12
+ let(:clock) { stub(:start_time => now, :start_date => today, :elapsed => 60) }
13
+
14
+ its(:duration) { should == 25.minutes }
15
+ its(:started_at) { should == now }
16
+ its(:date) { should == today }
17
+ its(:elapsed) { should == clock.elapsed }
18
+
19
+ it "update the duration" do
20
+ subject.duration = 5.minutes
21
+ subject.duration.should == 5.minutes
22
+ end
23
+ end
24
+
25
+ describe "comparison" do
26
+ it "is the same if the start-times match" do
27
+ clock = stub(:start_time => Time.new)
28
+ tomato_a = Tomato.new(25.minutes, clock)
29
+ tomato_b = Tomato.new(25.minutes, clock)
30
+
31
+ tomato_a.should eql(tomato_b)
32
+ end
33
+
34
+ # FIXME This ensures two tomatoes from the same
35
+ # time cannot co-exist, but it seems confusing
36
+ it "is the same if the duration differs" do
37
+ clock = stub(:start_time => Time.new)
38
+ tomato_a = Tomato.new(10.minutes, clock)
39
+ tomato_b = Tomato.new(20.minutes, clock)
40
+
41
+ tomato_a.should eql(tomato_b)
42
+ end
43
+ end
44
+
45
+ describe "remaining time" do
46
+ let(:clock) { stub(:elapsed => elapsed) }
47
+ let(:elapsed) { 0 }
48
+
49
+ context "when no time has elapsed" do
50
+ let(:elapsed) { 0 }
51
+ its(:remaining) { should == 25.minutes }
52
+ end
53
+
54
+ context "if some time has elapsed" do
55
+ let(:elapsed) { 10.minutes }
56
+ its(:remaining) { should == 15.minutes }
57
+ end
58
+
59
+ context "when all time has elapsed" do
60
+ let(:elapsed) { 25.minutes }
61
+ its(:remaining) { should == 0 }
62
+ end
63
+
64
+ context "when excessive time has elapsed" do
65
+ let(:elapsed) { 30.minutes }
66
+ its(:remaining) { should == 0 }
67
+ end
68
+
69
+ context "when it has been interrupted" do
70
+ before do
71
+ subject.interrupt!
72
+ end
73
+
74
+ its(:remaining) { should == 0 }
75
+ end
76
+ end
77
+
78
+ describe "states" do
79
+ let(:clock) { stub(:elapsed => elapsed) }
80
+ let(:elapsed) { 0 }
81
+
82
+ context "when just started" do
83
+ let(:elapsed) { 0 }
84
+ it { should be_active }
85
+ it { should_not be_completed }
86
+ it { should_not be_interrupted }
87
+ end
88
+
89
+ context "when time remains" do
90
+ let(:elapsed) { 15.minutes }
91
+ it { should be_active }
92
+ it { should_not be_completed }
93
+ it { should_not be_interrupted }
94
+ end
95
+
96
+ context "when time has elapsed" do
97
+ let(:elapsed) { 25.minutes }
98
+ it { should_not be_active }
99
+ it { should be_completed }
100
+ it { should_not be_interrupted }
101
+ end
102
+
103
+ context "when it has been interrupted" do
104
+ before do
105
+ subject.interrupt!
106
+ end
107
+
108
+ it { should be_interrupted }
109
+ it { should_not be_completed }
110
+ end
111
+
112
+ end
113
+
114
+ # it "can be distracted" ??
115
+
116
+ end
@@ -0,0 +1 @@
1
+ ---
@@ -0,0 +1,3 @@
1
+ ---
2
+ duration: 30
3
+ notifier: growl
data/tamarillo.gemspec ADDED
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/tamarillo/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.name = "tamarillo"
6
+ gem.version = Tamarillo::VERSION
7
+ gem.authors = ["Tim Uruski"]
8
+ gem.email = ["timuruski@gmail.com"]
9
+ gem.description = %q{Manage pomodoros from the command-line.}
10
+ gem.summary = %q{A command-line application for managing the pomodoro technique.}
11
+ gem.homepage = "https://github.com/timuruski/tamarillo"
12
+
13
+ gem.files = `git ls-files`.split($\)
14
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
15
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
16
+ gem.require_paths = ["lib"]
17
+
18
+ gem.add_development_dependency 'aruba', '~> 0.4.11'
19
+ gem.add_development_dependency 'active_support', '~> 3.0.0'
20
+ gem.add_development_dependency 'fakefs', '~> 0.4.0'
21
+ gem.add_development_dependency 'rspec', '~> 2.9.0'
22
+ gem.add_development_dependency 'timecop', '~> 0.3.5'
23
+
24
+ gem.add_runtime_dependency 'methadone', '~> 1.0.0.rc5'
25
+
26
+ end
metadata ADDED
@@ -0,0 +1,178 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tamarillo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Tim Uruski
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-06-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: aruba
16
+ requirement: &70235404161660 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.4.11
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70235404161660
25
+ - !ruby/object:Gem::Dependency
26
+ name: active_support
27
+ requirement: &70235404160820 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ~>
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ type: :development
34
+ prerelease: false
35
+ version_requirements: *70235404160820
36
+ - !ruby/object:Gem::Dependency
37
+ name: fakefs
38
+ requirement: &70235404160260 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: 0.4.0
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *70235404160260
47
+ - !ruby/object:Gem::Dependency
48
+ name: rspec
49
+ requirement: &70235404159400 !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: 2.9.0
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: *70235404159400
58
+ - !ruby/object:Gem::Dependency
59
+ name: timecop
60
+ requirement: &70235404158380 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ~>
64
+ - !ruby/object:Gem::Version
65
+ version: 0.3.5
66
+ type: :development
67
+ prerelease: false
68
+ version_requirements: *70235404158380
69
+ - !ruby/object:Gem::Dependency
70
+ name: methadone
71
+ requirement: &70235404157700 !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ~>
75
+ - !ruby/object:Gem::Version
76
+ version: 1.0.0.rc5
77
+ type: :runtime
78
+ prerelease: false
79
+ version_requirements: *70235404157700
80
+ description: Manage pomodoros from the command-line.
81
+ email:
82
+ - timuruski@gmail.com
83
+ executables:
84
+ - tam
85
+ extensions: []
86
+ extra_rdoc_files: []
87
+ files:
88
+ - .gitignore
89
+ - .travis.yml
90
+ - Gemfile
91
+ - LICENSE
92
+ - README.md
93
+ - Rakefile
94
+ - bin/tam
95
+ - features/config.feature
96
+ - features/step_definitions/tamarillo_steps.rb
97
+ - features/support/env.rb
98
+ - features/tamarillo.feature
99
+ - lib/tamarillo.rb
100
+ - lib/tamarillo/clock.rb
101
+ - lib/tamarillo/command.rb
102
+ - lib/tamarillo/config.rb
103
+ - lib/tamarillo/controller.rb
104
+ - lib/tamarillo/monitor.rb
105
+ - lib/tamarillo/notification.rb
106
+ - lib/tamarillo/notification/bell.rb
107
+ - lib/tamarillo/notification/growl.rb
108
+ - lib/tamarillo/notification/none.rb
109
+ - lib/tamarillo/notification/speech.rb
110
+ - lib/tamarillo/notification/touch.rb
111
+ - lib/tamarillo/storage.rb
112
+ - lib/tamarillo/tomato.rb
113
+ - lib/tamarillo/tomato_file.rb
114
+ - lib/tamarillo/version.rb
115
+ - spec/lib/tamarillo/clock_spec.rb
116
+ - spec/lib/tamarillo/command_spec.rb
117
+ - spec/lib/tamarillo/config_spec.rb
118
+ - spec/lib/tamarillo/controller_spec.rb
119
+ - spec/lib/tamarillo/monitor_spec.rb
120
+ - spec/lib/tamarillo/notification/bell_spec.rb
121
+ - spec/lib/tamarillo/notification/growl_spec.rb
122
+ - spec/lib/tamarillo/notification/speech_spec.rb
123
+ - spec/lib/tamarillo/notification_spec.rb
124
+ - spec/lib/tamarillo/storage_spec.rb
125
+ - spec/lib/tamarillo/tomato_file_spec.rb
126
+ - spec/lib/tamarillo/tomato_spec.rb
127
+ - spec/support/invalid-config.yml
128
+ - spec/support/sample-config.yml
129
+ - tamarillo.gemspec
130
+ homepage: https://github.com/timuruski/tamarillo
131
+ licenses: []
132
+ post_install_message:
133
+ rdoc_options: []
134
+ require_paths:
135
+ - lib
136
+ required_ruby_version: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ segments:
143
+ - 0
144
+ hash: 734855712674183534
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ! '>='
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ segments:
152
+ - 0
153
+ hash: 734855712674183534
154
+ requirements: []
155
+ rubyforge_project:
156
+ rubygems_version: 1.8.11
157
+ signing_key:
158
+ specification_version: 3
159
+ summary: A command-line application for managing the pomodoro technique.
160
+ test_files:
161
+ - features/config.feature
162
+ - features/step_definitions/tamarillo_steps.rb
163
+ - features/support/env.rb
164
+ - features/tamarillo.feature
165
+ - spec/lib/tamarillo/clock_spec.rb
166
+ - spec/lib/tamarillo/command_spec.rb
167
+ - spec/lib/tamarillo/config_spec.rb
168
+ - spec/lib/tamarillo/controller_spec.rb
169
+ - spec/lib/tamarillo/monitor_spec.rb
170
+ - spec/lib/tamarillo/notification/bell_spec.rb
171
+ - spec/lib/tamarillo/notification/growl_spec.rb
172
+ - spec/lib/tamarillo/notification/speech_spec.rb
173
+ - spec/lib/tamarillo/notification_spec.rb
174
+ - spec/lib/tamarillo/storage_spec.rb
175
+ - spec/lib/tamarillo/tomato_file_spec.rb
176
+ - spec/lib/tamarillo/tomato_spec.rb
177
+ - spec/support/invalid-config.yml
178
+ - spec/support/sample-config.yml