maid 0.10.0 → 0.11.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.
- checksums.yaml +4 -4
- data/.github/FUNDING.yml +14 -0
- data/.github/workflows/coverage.yml +3 -3
- data/.github/workflows/lint.yml +9 -1
- data/.github/workflows/merge-gatekeeper.yml +20 -0
- data/.github/workflows/release.yml +13 -20
- data/.github/workflows/stale.yml +25 -0
- data/.github/workflows/test.yml +8 -7
- data/.gitignore +1 -1
- data/.release-please-manifest.json +1 -1
- data/.rubocop.yml +3 -1
- data/.rubocop_todo.yml +105 -107
- data/.ruby-version +1 -1
- data/CHANGELOG.md +16 -0
- data/Dockerfile +13 -0
- data/Gemfile.lock +226 -0
- data/Guardfile +2 -0
- data/README.md +82 -49
- data/Rakefile +9 -0
- data/fixtures/files/test_rules.rb +3 -0
- data/lib/maid/logger/logger.rb +63 -0
- data/lib/maid/maid.rb +6 -22
- data/lib/maid/repeat.rb +2 -2
- data/lib/maid/rule.rb +2 -2
- data/lib/maid/rule_container.rb +2 -2
- data/lib/maid/tools.rb +3 -3
- data/lib/maid/trash_migration.rb +2 -0
- data/lib/maid/version.rb +1 -1
- data/lib/maid/watch.rb +2 -2
- data/lib/maid.rb +3 -2
- data/maid.gemspec +12 -9
- data/release-please-config.json +18 -0
- data/script/docker-test +7 -0
- data/spec/fakefs_helper.rb +13 -0
- data/spec/lib/maid/logger/logger_spec.rb +64 -0
- data/spec/lib/maid/maid_spec.rb +113 -103
- data/spec/lib/maid/rake/single_rule_spec.rb +1 -1
- data/spec/lib/maid/tools_spec.rb +383 -224
- data/spec/lib/maid/trash_migration_spec.rb +7 -5
- data/spec/spec_helper.rb +9 -1
- metadata +89 -42
- data/Vagrantfile +0 -14
- data/script/vagrant-provision +0 -43
- data/script/vagrant-test +0 -7
- data/script/vagrant-test-all +0 -34
data/lib/maid/rule.rb
CHANGED
data/lib/maid/rule_container.rb
CHANGED
@@ -3,9 +3,9 @@ module Maid::RuleContainer
|
|
3
3
|
attr_reader :rules
|
4
4
|
|
5
5
|
# initialize_rules
|
6
|
-
def initialize_rules(&
|
6
|
+
def initialize_rules(&)
|
7
7
|
@rules ||= []
|
8
|
-
instance_exec(&
|
8
|
+
instance_exec(&)
|
9
9
|
end
|
10
10
|
|
11
11
|
# Register a rule with a description and instructions (lambda function).
|
data/lib/maid/tools.rb
CHANGED
@@ -328,7 +328,7 @@ module Maid::Tools
|
|
328
328
|
def mkdir(path, options = {})
|
329
329
|
path = expand(path)
|
330
330
|
log("mkdir -p #{sh_escape(path)}")
|
331
|
-
FileUtils.mkdir_p(path, **@file_options
|
331
|
+
FileUtils.mkdir_p(path, **@file_options, **options)
|
332
332
|
path
|
333
333
|
end
|
334
334
|
|
@@ -727,7 +727,7 @@ module Maid::Tools
|
|
727
727
|
# where_content_type(dir('~/Downloads/*'), 'public.image')
|
728
728
|
def where_content_type(paths, filter_types)
|
729
729
|
filter_types = Array(filter_types)
|
730
|
-
Array(paths).select { |p|
|
730
|
+
Array(paths).select { |p| filter_types.intersect?(content_types(p)) }
|
731
731
|
end
|
732
732
|
|
733
733
|
# Test whether a directory is either empty, or contains only empty
|
@@ -739,7 +739,7 @@ module Maid::Tools
|
|
739
739
|
# trash('~/Downloads/foo')
|
740
740
|
# end
|
741
741
|
def tree_empty?(root)
|
742
|
-
return
|
742
|
+
return false if File.file?(root)
|
743
743
|
return true if Dir.glob(root + '/*').length == 0
|
744
744
|
|
745
745
|
ignore = []
|
data/lib/maid/trash_migration.rb
CHANGED
@@ -20,6 +20,8 @@ module Maid
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def perform
|
23
|
+
# FIXME: This is tightly coupled, we can't pass a custom log device
|
24
|
+
# etc.
|
23
25
|
maid = ::Maid::Maid.new(trash_path: correct_trash)
|
24
26
|
# Use local variable so it's available in the closure used by `instance_eval`
|
25
27
|
path = incorrect_trash
|
data/lib/maid/version.rb
CHANGED
data/lib/maid/watch.rb
CHANGED
@@ -5,7 +5,7 @@ class Maid::Watch
|
|
5
5
|
|
6
6
|
attr_reader :path, :listener, :logger
|
7
7
|
|
8
|
-
def initialize(maid, path, options = {}, &
|
8
|
+
def initialize(maid, path, options = {}, &)
|
9
9
|
@maid = maid
|
10
10
|
|
11
11
|
if options.nil? || options.empty?
|
@@ -19,7 +19,7 @@ class Maid::Watch
|
|
19
19
|
|
20
20
|
@logger = maid.logger # TODO: Maybe it's better to create seperate loggers?
|
21
21
|
@path = File.expand_path(path)
|
22
|
-
initialize_rules(&
|
22
|
+
initialize_rules(&)
|
23
23
|
end
|
24
24
|
|
25
25
|
def run
|
data/lib/maid.rb
CHANGED
@@ -4,6 +4,7 @@ Deprecated.set_action(:warn)
|
|
4
4
|
|
5
5
|
# Must be in this order:
|
6
6
|
require 'maid/version'
|
7
|
+
require 'maid/logger/logger'
|
7
8
|
require 'maid/downloading'
|
8
9
|
require 'maid/tools'
|
9
10
|
require 'maid/rule_container'
|
@@ -32,8 +33,8 @@ module Maid
|
|
32
33
|
end
|
33
34
|
|
34
35
|
# Define rules for the Maid instance.
|
35
|
-
def rules(&
|
36
|
-
@instance.instance_exec(&
|
36
|
+
def rules(&)
|
37
|
+
@instance.instance_exec(&)
|
37
38
|
end
|
38
39
|
end
|
39
40
|
end
|
data/maid.gemspec
CHANGED
@@ -23,7 +23,7 @@ Gem::Specification.new do |s|
|
|
23
23
|
|
24
24
|
s.rubyforge_project = 'maid'
|
25
25
|
|
26
|
-
s.required_ruby_version = '>= 2.
|
26
|
+
s.required_ruby_version = '>= 3.2.0'
|
27
27
|
|
28
28
|
# Strategy: if possible, use ranges (so there are fewer chances of version conflicts)
|
29
29
|
s.add_dependency('deprecated', '~> 3.0.0')
|
@@ -46,20 +46,23 @@ Gem::Specification.new do |s|
|
|
46
46
|
|
47
47
|
# Strategy: specific versions (since they're just for development)
|
48
48
|
s.add_development_dependency('fakefs', '~> 2.4.0')
|
49
|
-
s.add_development_dependency('fuubar')
|
49
|
+
s.add_development_dependency('fuubar', '~> 2.5.1')
|
50
50
|
s.add_development_dependency('guard', '~> 2.18.0')
|
51
51
|
s.add_development_dependency('guard-bundler', '~> 3.0.1')
|
52
52
|
s.add_development_dependency('guard-rspec', '~> 4.7.3')
|
53
|
-
s.add_development_dependency('guard-rubocop')
|
54
|
-
s.add_development_dependency('
|
53
|
+
s.add_development_dependency('guard-rubocop', '~> 1.5.0')
|
54
|
+
s.add_development_dependency('irb', '~> 1.15.1')
|
55
|
+
s.add_development_dependency('ostruct', '~> 0.6.1')
|
56
|
+
s.add_development_dependency('pry-byebug', '~> 3.10.1')
|
55
57
|
s.add_development_dependency('rake', '~> 13.0.6')
|
56
|
-
s.add_development_dependency('rake-notes')
|
58
|
+
s.add_development_dependency('rake-notes', '~> 0.2.2')
|
57
59
|
s.add_development_dependency('redcarpet', '~> 3.6.0') # Soft dependency of `yard`
|
60
|
+
s.add_development_dependency('reline', '~> 0.6.0')
|
58
61
|
s.add_development_dependency('rspec', '~> 3.12.0')
|
59
|
-
s.add_development_dependency('rubocop')
|
60
|
-
s.add_development_dependency('rubocop-rake')
|
61
|
-
s.add_development_dependency('rubocop-rspec')
|
62
|
-
s.add_development_dependency('simplecov')
|
62
|
+
s.add_development_dependency('rubocop', '~> 1.50')
|
63
|
+
s.add_development_dependency('rubocop-rake', '~> 0.6.0')
|
64
|
+
s.add_development_dependency('rubocop-rspec', '~> 3.5.0')
|
65
|
+
s.add_development_dependency('simplecov', '~> 0.22.0')
|
63
66
|
s.add_development_dependency('timecop', '~> 0.9.6')
|
64
67
|
s.add_development_dependency('vcr', '~> 6.1.0')
|
65
68
|
s.add_development_dependency('webmock', '~> 3.18.1')
|
@@ -0,0 +1,18 @@
|
|
1
|
+
{
|
2
|
+
"always-update": true,
|
3
|
+
"bootstrap-sha": "d4901ad446c8a614ef80472ed5e6f1ba8c702ed5",
|
4
|
+
"bump-minor-pre-major": true,
|
5
|
+
"bump-patch-for-minor-pre-major": true,
|
6
|
+
"commit-search-depth": 500,
|
7
|
+
"group-pull-request-title-pattern": "chore: release ${version}",
|
8
|
+
"release-search-depth": 400,
|
9
|
+
"release-type": "ruby",
|
10
|
+
"sequential-calls": false,
|
11
|
+
"packages": {
|
12
|
+
".": {
|
13
|
+
"release-type": "ruby",
|
14
|
+
"package-name": "maid",
|
15
|
+
"version-file": "lib/maid/version.rb"
|
16
|
+
}
|
17
|
+
}
|
18
|
+
}
|
data/script/docker-test
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
#!/usr/bin/env bash
|
2
|
+
|
3
|
+
# Run RSpec in a docker container, to avoid mistakenly writing to the live
|
4
|
+
# filesystem while developing.
|
5
|
+
docker rm -f maid-dev
|
6
|
+
docker build -t maid-dev .
|
7
|
+
docker run -it --rm --name maid-dev --mount type=bind,src="$(pwd)",target=/usr/src/app maid-dev
|
@@ -0,0 +1,13 @@
|
|
1
|
+
# FakeFS is missing #flock, see https://github.com/fakefs/fakefs/issues/433 and
|
2
|
+
# https://github.com/whitesmith/rubycritic/commit/57edc6244a9ebea8078a9c1dba32204ee7d1d895
|
3
|
+
|
4
|
+
# NOTE: This avoid NotImplementedError on File.flock, but causes a myriad of
|
5
|
+
# other issues since it doesn't really provide any locking in practice.
|
6
|
+
# If required, include this file in spec_helper.rb to monkey-patch FakeFS.
|
7
|
+
module FakeFS
|
8
|
+
class File < StringIO
|
9
|
+
def flock(*)
|
10
|
+
true
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'maid/logger/logger'
|
3
|
+
|
4
|
+
module Maid
|
5
|
+
# FakeFS not required because we're writing the log to /tmp/ and deleting it
|
6
|
+
# after the test.
|
7
|
+
describe Logger do
|
8
|
+
let(:logfile) { '/tmp/maid/test.log' }
|
9
|
+
let(:logger) { described_class.new(device: logfile) }
|
10
|
+
|
11
|
+
after { FileUtils.rm('/tmp/maid/test.log', force: true) }
|
12
|
+
|
13
|
+
levels = %i[debug info warn error fatal unknown]
|
14
|
+
levels.each do |level|
|
15
|
+
it "responds to #{level}" do
|
16
|
+
expect(logger).to respond_to(level)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
context 'with a filename' do
|
21
|
+
before { logger.info('test message') }
|
22
|
+
|
23
|
+
it 'creates that file' do
|
24
|
+
expect(File.exist?(logfile)).to be true
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'sets the default progname' do
|
28
|
+
expect(File.read(logfile)).to match(/Maid: /)
|
29
|
+
end
|
30
|
+
|
31
|
+
context 'with the ::Logger::DEBUG log level' do
|
32
|
+
let(:logger) { described_class.new(device: logfile, level: ::Logger::DEBUG) }
|
33
|
+
|
34
|
+
levels.each do |level|
|
35
|
+
it "logs #{level} messages" do
|
36
|
+
logger.send(level, "#{level} test message")
|
37
|
+
|
38
|
+
expect(File.read(logfile)).to match("#{level} test message")
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'works with a string' do
|
44
|
+
logger.info('test message')
|
45
|
+
|
46
|
+
expect(File.read(logfile)).to match 'test message'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'works with a custom progname and a block' do
|
50
|
+
logger.info('TestProgname') { 'test message' }
|
51
|
+
|
52
|
+
expect(File.read(logfile)).to match 'TestProgname: test message'
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with an IO' do
|
57
|
+
let(:logger) { described_class.new(device: StringIO.new) }
|
58
|
+
|
59
|
+
it 'is happy' do
|
60
|
+
expect { logger.info('test message') }.not_to raise_error
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
data/spec/lib/maid/maid_spec.rb
CHANGED
@@ -1,48 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
module Maid
|
4
|
-
describe Maid
|
5
|
-
let(:logger) {
|
4
|
+
describe Maid do
|
5
|
+
let(:logger) { class_spy(::Logger) }
|
6
|
+
let(:logfile) { '/tmp/maid-specs/test.log' }
|
7
|
+
let(:rules_file) { File.expand_path(File.join(File.dirname(__dir__), '../../fixtures/files/test_rules.rb')) }
|
8
|
+
let(:test_defaults) { Maid::DEFAULTS.merge({ log_device: logfile, rules_path: rules_file }) }
|
6
9
|
|
7
10
|
before do
|
8
|
-
|
11
|
+
FileUtils.mkdir_p(File.dirname(logfile))
|
12
|
+
# Avoid FakeFS error when the logfile doesn't already exist.
|
13
|
+
FileUtils.touch(logfile) if FakeFS.activated?
|
9
14
|
end
|
10
15
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'sets up a logger with the given path, when provided' do
|
18
|
-
log_device = '/var/log/maid.log'
|
19
|
-
expect(Logger).to receive(:new).with(log_device, anything, anything)
|
20
|
-
Maid.new(log_device: log_device)
|
21
|
-
end
|
16
|
+
after do
|
17
|
+
# Cleanup afterwards
|
18
|
+
FileUtils.rm_rf(File.dirname(logfile))
|
19
|
+
end
|
22
20
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
Maid.new
|
27
|
-
end
|
21
|
+
describe '.new' do
|
22
|
+
context 'with the default options' do
|
23
|
+
before { Maid.new(**test_defaults, logger: logger) }
|
28
24
|
|
29
|
-
|
30
|
-
|
31
|
-
|
25
|
+
it 'sets up a logger with the default path' do
|
26
|
+
expect(logger).to have_received(:new).with(device: test_defaults[:log_device])
|
27
|
+
end
|
32
28
|
end
|
33
29
|
|
34
|
-
|
35
|
-
|
30
|
+
context 'with a custom logfile path' do
|
31
|
+
let(:device) { '/tmp/maid-specs/overridden-maid.log' }
|
36
32
|
|
37
|
-
Maid.new(log_device:
|
33
|
+
before { Maid.new(log_device: device, logger: logger) }
|
38
34
|
|
39
|
-
|
35
|
+
it 'sets up a logger with the given path, when provided' do
|
36
|
+
expect(logger).to have_received(:new).with(device: device)
|
37
|
+
end
|
40
38
|
end
|
41
39
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
40
|
+
context 'with a custom logger' do
|
41
|
+
let(:maid) { Maid.new(logger: logger) }
|
42
|
+
|
43
|
+
it 'uses it' do
|
44
|
+
expect(maid.logger).to eq(logger)
|
45
|
+
end
|
46
46
|
end
|
47
47
|
|
48
48
|
describe 'platform-specific behavior' do
|
@@ -87,25 +87,14 @@ module Maid
|
|
87
87
|
end
|
88
88
|
end
|
89
89
|
|
90
|
-
|
91
|
-
trash_path
|
92
|
-
|
93
|
-
maid = Maid.new(trash_path: trash_path)
|
94
|
-
|
95
|
-
expect(maid.trash_path).not_to be_nil
|
96
|
-
expect(maid.trash_path).to eq(trash_path)
|
97
|
-
end
|
98
|
-
|
99
|
-
it 'sets the progname for the logger' do
|
100
|
-
Maid.new
|
101
|
-
|
102
|
-
expect(logger).to have_received(:progname=).with(Maid::DEFAULTS[:progname])
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'sets the progname for the logger to the given name, if provided' do
|
106
|
-
Maid.new(progname: 'Fran')
|
90
|
+
context 'with a custom trash path' do
|
91
|
+
let(:trash_path) { '/tmp/maid-specs/my_trash/' }
|
92
|
+
let(:maid) { Maid.new(log_device: test_defaults[:log_device], trash_path: trash_path) }
|
107
93
|
|
108
|
-
|
94
|
+
it 'sets the trash to the given path' do
|
95
|
+
expect(maid.trash_path).not_to be_nil
|
96
|
+
expect(maid.trash_path).to eq(trash_path)
|
97
|
+
end
|
109
98
|
end
|
110
99
|
|
111
100
|
it 'sets the file options to the defaults' do
|
@@ -133,21 +122,34 @@ module Maid
|
|
133
122
|
end
|
134
123
|
|
135
124
|
describe '#clean' do
|
125
|
+
let(:maid) { Maid.new(**test_defaults) }
|
126
|
+
|
136
127
|
before do
|
137
|
-
|
138
|
-
|
128
|
+
# Start with a clean logfile
|
129
|
+
FileUtils.rm_rf(logfile)
|
130
|
+
# Create the files that the test rules will impact
|
131
|
+
FileUtils.mkdir_p('/tmp/maid-specs')
|
132
|
+
FileUtils.touch('/tmp/maid-specs/perfect_man')
|
133
|
+
|
134
|
+
maid.load_rules
|
135
|
+
maid.clean
|
136
|
+
end
|
137
|
+
|
138
|
+
after do
|
139
|
+
FileUtils.rm_rf('/tmp/maid-specs')
|
139
140
|
end
|
140
141
|
|
141
|
-
it 'logs
|
142
|
-
|
142
|
+
it 'logs the beginning' do
|
143
|
+
expect(File.read(logfile)).to match(/Started/)
|
144
|
+
end
|
143
145
|
|
144
|
-
|
145
|
-
expect(
|
146
|
+
it 'logs the end' do
|
147
|
+
expect(File.read(logfile)).to match(/Finished/)
|
146
148
|
end
|
147
149
|
|
148
150
|
it 'follows the given rules' do
|
149
|
-
expect(
|
150
|
-
|
151
|
+
expect(File.exist?('/tmp/maid-specs/perfect_man')).to be false
|
152
|
+
expect(File.exist?('/tmp/maid-specs/buffalo_fuzz')).to be true
|
151
153
|
end
|
152
154
|
end
|
153
155
|
|
@@ -166,17 +168,17 @@ module Maid
|
|
166
168
|
end
|
167
169
|
|
168
170
|
context 'when there is a LoadError' do
|
169
|
-
let(:maid) { Maid.new }
|
171
|
+
let(:maid) { Maid.new(**test_defaults) }
|
170
172
|
|
171
173
|
before do
|
172
174
|
allow(Kernel).to receive(:load).and_raise(LoadError)
|
173
|
-
|
175
|
+
FileUtils.rm_rf(logfile)
|
174
176
|
end
|
175
177
|
|
176
178
|
it 'gives an error on STDERR if there is a LoadError' do
|
177
179
|
maid.load_rules
|
178
180
|
|
179
|
-
expect(
|
181
|
+
expect(File.read(logfile)).to match(/LoadError/)
|
180
182
|
end
|
181
183
|
end
|
182
184
|
end
|
@@ -218,30 +220,37 @@ module Maid
|
|
218
220
|
end
|
219
221
|
|
220
222
|
# FIXME: Example is too long, shouldn't need the rubocop::disable
|
221
|
-
|
222
|
-
hash
|
223
|
-
|
223
|
+
context 'with a hash of options' do
|
224
|
+
let(:hash) { { some: :options } }
|
225
|
+
let(:listener) { double('listener') }
|
224
226
|
|
225
|
-
|
226
|
-
|
227
|
+
before do
|
228
|
+
FileUtils.mkdir_p('some_dir')
|
229
|
+
@maid.watch('some_dir', hash) do
|
230
|
+
rule 'test' do
|
231
|
+
end
|
227
232
|
end
|
228
233
|
end
|
229
234
|
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
end
|
235
|
+
it 'passes them to Listen' do
|
236
|
+
expect(Listen).to receive(:to) do |dir, opts|
|
237
|
+
expect(dir).to eq File.expand_path('some_dir')
|
238
|
+
expect(opts).to eq(hash)
|
239
|
+
listener
|
240
|
+
end
|
237
241
|
|
238
|
-
|
242
|
+
expect(listener).to receive(:start)
|
239
243
|
|
240
|
-
|
244
|
+
@maid.watches.last.run
|
245
|
+
end
|
241
246
|
end
|
242
247
|
|
243
248
|
context('with a non-existent directory') do
|
244
|
-
let(:maid) { Maid.new }
|
249
|
+
let(:maid) { Maid.new(**test_defaults) }
|
250
|
+
|
251
|
+
before do
|
252
|
+
FileUtils.rm_rf(logfile)
|
253
|
+
end
|
245
254
|
|
246
255
|
it 'raises with an intelligible message' do
|
247
256
|
expect { maid.watch('/doesnt_exist/') }.to raise_error(/file.*exist/)
|
@@ -256,14 +265,18 @@ module Maid
|
|
256
265
|
rescue StandardError # rubocop:disable Lint/SuppressedException
|
257
266
|
end
|
258
267
|
|
259
|
-
expect(
|
268
|
+
expect(File.read(logfile)).to match(/file.*exist/)
|
260
269
|
end
|
261
270
|
end
|
262
271
|
end
|
263
272
|
|
264
|
-
describe '#repeat', fake_zoneinfo:
|
273
|
+
describe '#repeat', fake_zoneinfo: false do
|
265
274
|
before do
|
266
|
-
|
275
|
+
# Avoid FakeFS error when the logfile doesn't already exist.
|
276
|
+
FileUtils.mkdir_p(File.dirname(logfile))
|
277
|
+
FileUtils.touch(logfile)
|
278
|
+
|
279
|
+
@maid = Maid.new(log_device: logfile)
|
267
280
|
end
|
268
281
|
|
269
282
|
it 'adds a repeat to the list of repeats' do
|
@@ -277,53 +290,50 @@ module Maid
|
|
277
290
|
expect(@maid.repeats.first.timestring).to eq('1s')
|
278
291
|
end
|
279
292
|
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
293
|
+
context 'with a hash of options' do
|
294
|
+
let(:scheduler) { double('scheduler') }
|
295
|
+
let(:hash) { { some: :options } }
|
296
|
+
|
297
|
+
before do
|
298
|
+
allow(Rufus::Scheduler).to receive(:singleton).and_return(scheduler)
|
284
299
|
|
285
|
-
|
286
|
-
|
287
|
-
|
300
|
+
@maid.repeat('1s', hash) do
|
301
|
+
rule 'test' do
|
302
|
+
end
|
288
303
|
end
|
289
304
|
end
|
290
305
|
|
291
|
-
|
306
|
+
it 'passes them to Rufus' do
|
307
|
+
expect(scheduler).to receive(:repeat).with('1s', hash)
|
292
308
|
|
293
|
-
|
309
|
+
@maid.repeats.last.run
|
310
|
+
end
|
294
311
|
end
|
295
312
|
end
|
296
313
|
|
297
314
|
describe '#follow_rules' do
|
298
|
-
|
299
|
-
it 'follows each rule' do # rubocop:disable RSpec/ExampleLength
|
300
|
-
n = 3
|
301
|
-
maid = Maid.new
|
302
|
-
|
303
|
-
rules = (1..n).map do |i|
|
304
|
-
d = double("rule ##{i}", description: 'description')
|
305
|
-
expect(d).to receive(:follow)
|
306
|
-
d
|
307
|
-
end
|
308
|
-
maid.instance_eval { @rules = rules }
|
315
|
+
let(:maid) { Maid.new(**test_defaults) }
|
309
316
|
|
317
|
+
it 'follows each rule' do
|
318
|
+
# FIXME: This should run in a before and rules should be a let, but it
|
319
|
+
# fails when arranged that way.
|
320
|
+
rules = [spy(Rule), spy(Rule), spy(Rule)]
|
321
|
+
maid.instance_eval { @rules = rules }
|
310
322
|
maid.follow_rules
|
311
323
|
|
312
|
-
expect(
|
324
|
+
expect(rules).to all(have_received(:follow).once)
|
313
325
|
end
|
314
326
|
end
|
315
327
|
|
316
328
|
describe '#cmd' do
|
317
|
-
|
318
|
-
@maid = Maid.new
|
319
|
-
end
|
329
|
+
let(:maid) { Maid.new(log_device: logfile) }
|
320
330
|
|
321
331
|
it 'reports `not-a-real-command` as not being a supported command' do
|
322
|
-
expect {
|
332
|
+
expect { maid.cmd('not-a-real-command arg1 arg2') }.to raise_error(NotImplementedError)
|
323
333
|
end
|
324
334
|
|
325
335
|
it 'reports `echo` as a real command' do
|
326
|
-
expect {
|
336
|
+
expect { maid.cmd('echo .') }.not_to raise_error
|
327
337
|
end
|
328
338
|
end
|
329
339
|
end
|