download_tv 2.6.6 → 2.6.7

Sign up to get free protection for your applications and to get access to all the features.
@@ -4,26 +4,49 @@ module DownloadTV
4
4
  ##
5
5
  # Class in charge of managing the link grabbers
6
6
  class Torrent
7
- attr_reader :g_instances, :tries
7
+ class << self
8
+ def grabbers
9
+ %w[TorrentAPI Torrentz Eztv]
10
+ end
8
11
 
9
- def grabbers
10
- %w[TorrentAPI Torrentz Eztv]
12
+ def healthcheck
13
+ grabbers.each do |g|
14
+ grabber = (DownloadTV.const_get g).new
15
+ puts "#{g}: #{grabber.online? ? 'online' : 'offline'}"
16
+ end
17
+ end
11
18
  end
12
19
 
13
20
  def initialize(default_grabber = nil)
14
- g_names = grabbers
15
-
16
- # Silently ignores bad names
17
- found_default = g_names.find_index(default_grabber)
18
- g_names.rotate! found_default if found_default
19
-
20
- @g_instances = g_names.map { |g| (DownloadTV.const_get g).new }
21
+ @g_instances = self.class.grabbers\
22
+ .rotate(self.class.grabbers.find_index(default_grabber) || 0)
23
+ .map { |g| (DownloadTV.const_get g).new }
21
24
  reset_tries
22
25
 
23
- check_grabber_online
26
+ remove_grabber_if_offline
24
27
  end
25
28
 
26
- def check_grabber_online
29
+ def get_links(show)
30
+ @g_instances.first.get_links(show)
31
+ rescue NoTorrentsError
32
+ if @tries.positive?
33
+ change_grabbers
34
+ retry
35
+ end
36
+ # We're out of grabbers to try
37
+ puts "No torrents found for #{show}"
38
+ []
39
+ ensure
40
+ reset_grabbers_order
41
+ end
42
+
43
+ private
44
+
45
+ ##
46
+ # This method removes the grabber from the instances list if it is not online
47
+ # It will repeat until it finds an online grabber, or exit the application
48
+ # if there are none
49
+ def remove_grabber_if_offline
27
50
  if @g_instances.empty?
28
51
  warn 'There are no available grabbers.'
29
52
  exit 1
@@ -34,27 +57,13 @@ module DownloadTV
34
57
  warn "Problem accessing #{@g_instances.first.class.name}"
35
58
  @tries -= 1
36
59
  @g_instances.shift # Removes first element
37
- check_grabber_online
60
+ remove_grabber_if_offline
38
61
  end
39
62
 
40
63
  def change_grabbers
41
64
  @tries -= 1
42
65
  @g_instances.rotate!
43
- check_grabber_online
44
- end
45
-
46
- def get_links(show)
47
- @g_instances.first.get_links(show)
48
- rescue NoTorrentsError
49
- if @tries.positive?
50
- change_grabbers
51
- retry
52
- end
53
- # We're out of grabbers to try
54
- puts "No torrents found for #{show}"
55
- []
56
- ensure
57
- reset_grabbers_order
66
+ remove_grabber_if_offline
58
67
  end
59
68
 
60
69
  def reset_tries
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module DownloadTV
4
- VERSION = '2.6.6'
4
+ VERSION = '2.6.7'
5
5
  end
@@ -0,0 +1,199 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe DownloadTV::Configuration do
4
+ let(:raw_config) { double('raw_config') }
5
+ let(:parsed_config) { { version: DownloadTV::VERSION, pending: [] } }
6
+ let(:opts) { {} }
7
+ subject { described_class.new(opts) }
8
+
9
+ before :each do
10
+ allow(File).to receive(:exist?).and_return true
11
+ allow(File).to receive(:read).and_return raw_config
12
+ allow(JSON).to receive(:parse).and_return parsed_config
13
+ end
14
+
15
+ describe '#[] and #[]=' do
16
+ it 'will set and get values of the underlying hash' do
17
+ subject[:test] = :any
18
+ expect(subject[:test]).to eq(:any)
19
+ end
20
+ end
21
+
22
+ describe '#initialize' do
23
+ context 'when the config file exists' do
24
+ context 'when options are given' do
25
+ let(:opts) { { myepisodes_user: 'test', pending: [1], ignored: ['aAAa'] } }
26
+ it 'will apply them to the final config' do
27
+ expect(subject[:myepisodes_user]).to eq opts[:myepisodes_user]
28
+ expect(subject[:pending]).to eq opts[:pending]
29
+ end
30
+
31
+ it 'will downcase strings in :ignored' do
32
+ expect(subject[:ignored].first).to eq opts[:ignored].first.downcase
33
+ end
34
+ end
35
+ end
36
+
37
+ context 'when the config file does not exist' do
38
+ before :each do
39
+ allow(File).to receive(:exist?).and_return false
40
+ allow(FileUtils).to receive(:mkdir_p)
41
+ allow_any_instance_of(described_class).to receive(:change_configuration)
42
+ allow_any_instance_of(described_class).to receive(:serialize)
43
+ end
44
+
45
+ context 'when options are given' do
46
+ let(:opts) { { myepisodes_user: 'test' } }
47
+
48
+ it 'will override the other values' do
49
+ expect(subject[:myepisodes_user]).to eq opts[:myepisodes_user]
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ describe '#change_configuration' do
56
+ let(:myepisodes_user) { 'myep' }
57
+ let(:cookies) { 'n' }
58
+ let(:ignored) { 'ignored1,ignored2' }
59
+
60
+ before :each do
61
+ allow(File).to receive(:exist?).and_return false
62
+ allow(FileUtils).to receive(:mkdir_p)
63
+ allow_any_instance_of(described_class).to receive(:serialize)
64
+ allow($stdin).to receive(:gets).and_return(myepisodes_user, cookies, ignored, '', '')
65
+ end
66
+
67
+ it 'will create a new config with the given and the default values' do
68
+ expect(subject[:myepisodes_user]).to eq myepisodes_user
69
+ expect(subject[:cookie]).to be false
70
+ expect(subject[:auto]).to be true
71
+ expect(subject[:ignored].size).to eq 2
72
+ expect(subject[:date]).to eq(Date.today - 1)
73
+ expect(subject[:filters]).not_to be_nil
74
+ expect(subject[:version]).not_to be_nil
75
+ expect(subject[:pending]).not_to be_nil
76
+ expect(subject[:grabber]).not_to be_nil
77
+ end
78
+ end
79
+
80
+ describe '#serialize' do
81
+ let(:parsed_config) { { version: DownloadTV::VERSION, pending: [1, 1, 2] } }
82
+
83
+ before :each do
84
+ allow(File).to receive(:write).and_return nil
85
+ end
86
+
87
+ it 'will remove duplicates from :pending' do
88
+ subject.serialize
89
+ expect(subject[:pending].size).to eq 2
90
+ end
91
+
92
+ it 'will write to a file' do
93
+ expect(File).to receive(:write)
94
+ subject.serialize
95
+ end
96
+
97
+ context 'when a path is given in the options' do
98
+ let(:opts) { { path: '/tmp/test' } }
99
+ it 'will write to a file in our given path' do
100
+ config = double('config')
101
+ expect(JSON).to receive(:generate).and_return(config)
102
+ expect(File).to receive(:write).with(opts[:path], config)
103
+ subject.serialize
104
+ end
105
+ end
106
+ end
107
+
108
+ describe '#to_s' do
109
+ it 'will form a string with each (key, value) pair in a new line' do
110
+ expected = "version: #{DownloadTV::VERSION}\n"\
111
+ "pending: []\n"
112
+ expect(subject.to_s).to eq expected
113
+ end
114
+ end
115
+
116
+ describe '#clear_pending' do
117
+ it 'will clear :pending and call serialize' do
118
+ subject[:pending] << double
119
+ expect(subject).to receive(:serialize)
120
+ expect(subject[:pending].size).to eq 1
121
+ subject.clear_pending
122
+ expect(subject[:pending].size).to eq 0
123
+ end
124
+ end
125
+
126
+ describe '#queue_pending' do
127
+ it 'will add an item to :pending and serialize' do
128
+ expect(subject).to receive(:serialize)
129
+ expect(subject[:pending].size).to eq 0
130
+ subject.queue_pending(double)
131
+ expect(subject[:pending].size).to eq 1
132
+ end
133
+ end
134
+
135
+ context 'breaking changes:' do
136
+ let(:version) { nil }
137
+ let(:parsed_config) do
138
+ {
139
+ version: version
140
+ }
141
+ end
142
+
143
+ before :each do
144
+ stub_const('DownloadTV::VERSION', '2.1.10')
145
+ allow(File).to receive(:exist?).and_return true
146
+ allow(File).to receive(:read).and_return raw_config
147
+ allow(JSON).to receive(:parse).and_return parsed_config
148
+ end
149
+
150
+ describe 'when the config does not have a version' do
151
+ it 'will trigger a config update' do
152
+ expect_any_instance_of(described_class).to receive(:change_configuration).once.and_return nil
153
+ subject
154
+ end
155
+ end
156
+
157
+ describe 'when the app version is newer (patch)' do
158
+ let(:version) { '2.1.9' }
159
+ it 'will NOT trigger a config update' do
160
+ expect_any_instance_of(described_class).not_to receive(:change_configuration)
161
+ subject
162
+ end
163
+ end
164
+
165
+ describe 'when the app version is the same' do
166
+ let(:version) { '2.1.10' }
167
+ it 'will NOT trigger a config update' do
168
+ expect_any_instance_of(described_class).not_to receive(:change_configuration)
169
+ subject
170
+ end
171
+ end
172
+
173
+ describe 'when the app version is newer (minor)' do
174
+ let(:version) { '2.0.19' }
175
+
176
+ it 'will trigger a config update' do
177
+ expect_any_instance_of(described_class).to receive(:change_configuration).once.and_return nil
178
+ subject
179
+ end
180
+ end
181
+
182
+ describe 'when the app version is newer (major)' do
183
+ let(:version) { '1.20.999' }
184
+
185
+ it 'will trigger a config update' do
186
+ expect_any_instance_of(described_class).to receive(:change_configuration).once.and_return nil
187
+ subject
188
+ end
189
+ end
190
+
191
+ describe 'when the app version is older (any)' do
192
+ let(:version) { '2.1.11' }
193
+ it 'will trigger a config update' do
194
+ expect_any_instance_of(described_class).to receive(:change_configuration).once.and_return nil
195
+ subject
196
+ end
197
+ end
198
+ end
199
+ end
@@ -0,0 +1,107 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe DownloadTV::Filterer do
4
+ let(:excludes) { [] }
5
+ let(:includes) { [] }
6
+ let(:filters_config) { { excludes: excludes, includes: includes } }
7
+
8
+ subject { described_class.new(filters_config) }
9
+
10
+ describe '#filter' do
11
+ let(:test_data) do
12
+ [
13
+ 'Test 12',
14
+ 'Test 10',
15
+ 'Exclude'
16
+ ]
17
+ end
18
+
19
+ context 'when there are no filters' do
20
+ it 'will return the given list' do
21
+ expect(subject.filter(test_data)).to eq test_data
22
+ end
23
+ end
24
+
25
+ context 'when there are exclude filters' do
26
+ describe 'when there is only one entry not matching (one filter)' do
27
+ let(:excludes) { ['TEST'] }
28
+ it 'will return it' do
29
+ filtered = subject.filter(test_data)
30
+ expect(filtered.size).to eq 1
31
+ expect(filtered.first).to eq 'Exclude'
32
+ end
33
+ end
34
+
35
+ describe 'when there is only one entry not matching (multiple filter)' do
36
+ let(:excludes) { ['2', '0'] }
37
+ it 'will return it' do
38
+ filtered = subject.filter(test_data)
39
+ expect(filtered.size).to eq 1
40
+ expect(filtered.first).to eq 'Exclude'
41
+ end
42
+ end
43
+
44
+ describe 'when only one filter matches' do
45
+ let(:excludes) { ['0'] }
46
+ it 'will not return that element' do
47
+ filtered = subject.filter(test_data)
48
+ expect(filtered.size).to eq 2
49
+ expect(filtered.include?('Test 10')).to be false
50
+ end
51
+ end
52
+
53
+ describe 'when no entries match' do
54
+ let(:excludes) { ['zzzz'] }
55
+ it 'will return the original' do
56
+ filtered = subject.filter(test_data)
57
+ expect(filtered).to eq test_data
58
+ end
59
+ end
60
+
61
+ describe 'when all entries match (one filter)' do
62
+ let(:excludes) { ['E'] }
63
+ it 'will return the original' do
64
+ filtered = subject.filter(test_data)
65
+ expect(filtered).to eq test_data
66
+ end
67
+ end
68
+
69
+ describe 'when all entries match (more filters)' do
70
+ let(:excludes) { ['TEST', 'EXCLUDE'] }
71
+ it 'will only apply filters until there would be no values left' do
72
+ filtered = subject.filter(test_data)
73
+ expect(filtered.size).to eq 1
74
+ expect(filtered.first).to eq 'Exclude'
75
+ end
76
+ end
77
+ end
78
+
79
+ context 'when there are include filters' do
80
+ let(:includes) { ['TEST'] }
81
+ it 'will filter out entries not matching' do
82
+ filtered = subject.filter(test_data)
83
+ expect(filtered.size).to eq 2
84
+ expect(filtered.include?('Exclude')).to be false
85
+ end
86
+ end
87
+
88
+ context 'when there are both types of filters' do
89
+ let(:excludes) { ['EXCLUDE'] }
90
+ let(:includes) { ['EXCLUDE'] }
91
+
92
+ it 'will apply "includes" filters first' do
93
+ filtered = subject.filter(test_data)
94
+ expect(filtered.size).to eq 1
95
+ expect(filtered.first).to eq 'Exclude'
96
+ end
97
+
98
+ describe 'if the filters are not capitalised' do
99
+ let(:excludes) { ['exclude'] }
100
+ let(:includes) { ['test'] }
101
+ it 'will not apply the filter successfully' do
102
+ expect(subject.filter(test_data)).to eq test_data
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe DownloadTV::LinkGrabber do
4
+ # TODO: Write specs for the individual grabbers (see #4)
5
+ # grabbers = DownloadTV::Torrent.grabbers
6
+ # instances = grabbers.map { |g| (DownloadTV.const_get g).new }
7
+
8
+ # instances.each do |grabber|
9
+ # describe grabber do
10
+ # end
11
+ # end
12
+
13
+ it "raises an error if the instance doesn't implement get_links" do
14
+ expect { DownloadTV::LinkGrabber.new(double).get_links(double) }.to raise_error(NotImplementedError)
15
+ end
16
+ end
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe DownloadTV::MyEpisodes do
4
+ let(:save_cookie) { true }
5
+ let(:page) { double('page') }
6
+ let(:agent) { double('agent', :user_agent= => nil, get: page) }
7
+ let(:cookie_jar) { double('cookie_jar') }
8
+ subject { described_class.new('user', true) }
9
+
10
+ before :each do
11
+ allow(Mechanize).to receive(:new).and_return agent
12
+ allow(agent).to receive(:cookie_jar).and_return cookie_jar
13
+ allow(cookie_jar).to receive(:load)
14
+ allow(cookie_jar).to receive(:save)
15
+ end
16
+
17
+ describe '#initialize' do
18
+ context 'when cookie does not load' do
19
+ it 'will execute a user/password login' do
20
+ allow_any_instance_of(described_class).to receive(:load_cookie).and_return false
21
+ expect_any_instance_of(described_class).to receive(:manual_login).once.and_return nil
22
+ subject
23
+ end
24
+ end
25
+
26
+ context 'when using a valid cookie' do
27
+ it 'will log in via cookie' do
28
+ allow_any_instance_of(described_class).to receive(:load_cookie).and_return true
29
+ expect_any_instance_of(described_class).not_to receive(:manual_login)
30
+ subject
31
+ end
32
+ end
33
+ end
34
+
35
+ describe '#get_shows_since' do
36
+ # TODO
37
+ end
38
+ end
@@ -0,0 +1,132 @@
1
+ # frozen_string_literal: true
2
+
3
+ describe DownloadTV::Torrent do
4
+ let(:default_grabber) { nil }
5
+ let(:eztv_mock) { double('eztv') }
6
+ let(:torrentapi_mock) { double('torrentapi') }
7
+ let(:torrentz_mock) { double('torrentz') }
8
+ let(:tpb_mock) { double('tpb') }
9
+ let(:test_show) { double('test_show') }
10
+ subject { described_class.new(default_grabber) }
11
+
12
+ before :each do
13
+ allow(DownloadTV::TorrentAPI).to receive(:new).and_return torrentapi_mock
14
+ allow(DownloadTV::Torrentz).to receive(:new).and_return torrentz_mock
15
+ allow(DownloadTV::Eztv).to receive(:new).and_return eztv_mock
16
+ # allow(DownloadTV::ThePirateBay).to receive(:new).and_return tpb_mock
17
+
18
+ allow(torrentapi_mock).to receive(:online?).and_return(true)
19
+ allow(torrentz_mock).to receive(:online?).and_return(true)
20
+ allow(eztv_mock).to receive(:online?).and_return(true)
21
+ end
22
+
23
+ describe 'Torrent.grabbers' do
24
+ it 'returns the list of grabbers' do
25
+ # This order is assumed in the other specs, so explicitly checking it here
26
+ expect(described_class.grabbers).to eq %w[TorrentAPI Torrentz Eztv]
27
+
28
+ end
29
+ end
30
+
31
+ describe '#get_links' do
32
+ it 'will use the first grabber and return its #get_link result' do
33
+ result = double('result')
34
+ expect(torrentapi_mock).to receive(:get_links).with(test_show).and_return(result)
35
+
36
+ result = subject.get_links(test_show)
37
+ end
38
+
39
+ context 'when the first grabber is offline' do
40
+ before do
41
+ allow(torrentapi_mock).to receive(:online?).and_return(false)
42
+ end
43
+
44
+ it 'will use the second grabber' do
45
+ expect(torrentapi_mock).not_to receive(:get_links)
46
+ expect(eztv_mock).not_to receive(:get_links)
47
+ expect(torrentz_mock).to receive(:get_links).with(test_show)
48
+
49
+ result = subject.get_links(test_show)
50
+ end
51
+ end
52
+
53
+ context 'when all the grabbers are offline' do
54
+ before do
55
+ allow(torrentapi_mock).to receive(:online?).and_return(false)
56
+ allow(torrentz_mock).to receive(:online?).and_return(false)
57
+ allow(eztv_mock).to receive(:online?).and_return(false)
58
+ end
59
+
60
+ it 'will exit' do
61
+ expect(torrentapi_mock).not_to receive(:get_links)
62
+ expect(torrentz_mock).not_to receive(:get_links)
63
+ expect(eztv_mock).not_to receive(:get_links)
64
+
65
+ expect { subject.get_links(test_show) }.to raise_error(SystemExit)
66
+ end
67
+ end
68
+
69
+ context 'when one grabber does not find a link' do
70
+ before do
71
+ allow(torrentapi_mock).to receive(:get_links).with(test_show).and_raise(DownloadTV::NoTorrentsError)
72
+ allow(torrentz_mock).to receive(:get_links).with(test_show).and_raise(DownloadTV::NoTorrentsError)
73
+ end
74
+
75
+ it 'will keep trying until one does' do
76
+ expect(torrentapi_mock).to receive(:get_links).ordered
77
+ expect(torrentz_mock).to receive(:get_links).ordered
78
+ expect(eztv_mock).to receive(:get_links).ordered
79
+
80
+ result = subject.get_links(test_show)
81
+ end
82
+ end
83
+
84
+ context 'when no grabber can find a link' do
85
+ before do
86
+ allow(torrentapi_mock).to receive(:get_links).with(test_show).and_raise(DownloadTV::NoTorrentsError)
87
+ allow(torrentz_mock).to receive(:get_links).with(test_show).and_raise(DownloadTV::NoTorrentsError)
88
+ allow(eztv_mock).to receive(:get_links).with(test_show).and_raise(DownloadTV::NoTorrentsError)
89
+ end
90
+
91
+ it 'will return an empty array' do
92
+ expect(torrentapi_mock).to receive(:get_links).ordered
93
+ expect(torrentz_mock).to receive(:get_links).ordered
94
+ expect(eztv_mock).to receive(:get_links).ordered
95
+
96
+ expect(subject.get_links(test_show)).to eq []
97
+ end
98
+ end
99
+
100
+ context 'when the default grabber is set' do
101
+ let(:default_grabber) { 'Eztv' }
102
+
103
+ it 'will use that grabber preferently' do
104
+ test_show = double('test_show')
105
+ expect(torrentapi_mock).not_to receive(:get_links)
106
+ expect(torrentz_mock).not_to receive(:get_links)
107
+ expect(eztv_mock).to receive(:get_links).with(test_show)
108
+
109
+ result = subject.get_links(test_show)
110
+ end
111
+ end
112
+
113
+ context 'when a grabber fails on a run and it is called twice' do
114
+ before do
115
+ count = 0
116
+ allow(torrentapi_mock).to receive(:get_links).exactly(2).times.with(test_show) do
117
+ count += 1
118
+ raise DownloadTV::NoTorrentsError if count == 1
119
+ end
120
+
121
+ end
122
+
123
+ it 'the second run will use the original order' do
124
+ expect(torrentapi_mock).to receive(:get_links).exactly(2).times
125
+ expect(torrentz_mock).to receive(:get_links).exactly(1).time
126
+
127
+ result = subject.get_links(test_show)
128
+ result = subject.get_links(test_show)
129
+ end
130
+ end
131
+ end
132
+ end
@@ -0,0 +1,92 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file was generated by the `rspec --init` command. Conventionally, all
4
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
5
+ # The generated `.rspec` file contains `--require spec_helper` which will cause
6
+ # this file to always be loaded, without a need to explicitly require it in any
7
+ # files.
8
+ require 'download_tv'
9
+ #
10
+ # Given that it is always loaded, you are encouraged to keep this file as
11
+ # light-weight as possible. Requiring heavyweight dependencies from this file
12
+ # will add to the boot time of your test suite on EVERY test run, even for an
13
+ # individual file that may not need all of that loaded. Instead, consider making
14
+ # a separate helper file that requires the additional dependencies and performs
15
+ # the additional setup, and require it from the spec files that actually need
16
+ # it.
17
+ #
18
+ # See https://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
19
+ RSpec.configure do |config|
20
+ # rspec-expectations config goes here. You can use an alternate
21
+ # assertion/expectation library such as wrong or the stdlib/minitest
22
+ # assertions if you prefer.
23
+ config.expect_with :rspec do |expectations|
24
+ # This option will default to `true` in RSpec 4. It makes the `description`
25
+ # and `failure_message` of custom matchers include text for helper methods
26
+ # defined using `chain`, e.g.:
27
+ # be_bigger_than(2).and_smaller_than(4).description
28
+ # # => "be bigger than 2 and smaller than 4"
29
+ # ...rather than:
30
+ # # => "be bigger than 2"
31
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32
+ end
33
+
34
+ # rspec-mocks config goes here. You can use an alternate test double
35
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
36
+ config.mock_with :rspec do |mocks|
37
+ # Prevents you from mocking or stubbing a method that does not exist on
38
+ # a real object. This is generally recommended, and will default to
39
+ # `true` in RSpec 4.
40
+ mocks.verify_partial_doubles = true
41
+ end
42
+
43
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
44
+ # have no way to turn it off -- the option exists only for backwards
45
+ # compatibility in RSpec 3). It causes shared context metadata to be
46
+ # inherited by the metadata hash of host groups and examples, rather than
47
+ # triggering implicit auto-inclusion in groups with matching metadata.
48
+ config.shared_context_metadata_behavior = :apply_to_host_groups
49
+
50
+ # The settings below are suggested to provide a good initial experience
51
+ # with RSpec, but feel free to customize to your heart's content.
52
+ # Allows RSpec to persist some state between runs in order to support
53
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
54
+ # you configure your source control system to ignore this file.
55
+ # config.example_status_persistence_file_path = "spec/examples.txt"
56
+
57
+ # Limits the available syntax to the non-monkey patched syntax that is
58
+ # recommended. For more details, see:
59
+ # https://relishapp.com/rspec/rspec-core/docs/configuration/zero-monkey-patching-mode
60
+ # config.disable_monkey_patching!
61
+
62
+ # This setting enables warnings. It's recommended, but in some cases may
63
+ # be too noisy due to issues in dependencies.
64
+ # config.warnings = true
65
+
66
+ # Many RSpec users commonly either run the entire suite or an individual
67
+ # file, and it's useful to allow more verbose output when running an
68
+ # individual spec file.
69
+ # if config.files_to_run.one?
70
+ # Use the documentation formatter for detailed output,
71
+ # unless a formatter has already been configured
72
+ # (e.g. via a command-line flag).
73
+ # config.default_formatter = "doc"
74
+ # end
75
+
76
+ # Print the 10 slowest examples and example groups at the
77
+ # end of the spec run, to help surface which specs are running
78
+ # particularly slow.
79
+ # config.profile_examples = 10
80
+
81
+ # Run specs in random order to surface order dependencies. If you find an
82
+ # order dependency and want to debug it, you can fix the order by providing
83
+ # the seed, which is printed after each run.
84
+ # --seed 1234
85
+ # config.order = :random
86
+
87
+ # Seed global randomization in this process using the `--seed` CLI option.
88
+ # Setting this allows you to use `--seed` to deterministically reproduce
89
+ # test failures related to randomization by passing the same `--seed` value
90
+ # as the one that triggered the failure.
91
+ # Kernel.srand config.seed
92
+ end