copy_tuner_client 2.1.2 → 2.2.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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -0
  3. data/.rubocop.yml +46 -1
  4. data/CLAUDE.md +1 -0
  5. data/Gemfile +1 -0
  6. data/copy_tuner_client.gemspec +3 -3
  7. data/gemfiles/8.0.gemfile +3 -3
  8. data/gemfiles/8.1.gemfile +3 -3
  9. data/gemfiles/main.gemfile +3 -3
  10. data/lib/copy_tuner_client/cache.rb +34 -27
  11. data/lib/copy_tuner_client/client.rb +35 -23
  12. data/lib/copy_tuner_client/configuration.rb +62 -40
  13. data/lib/copy_tuner_client/copyray/rewriter.rb +1 -1
  14. data/lib/copy_tuner_client/copyray.rb +1 -0
  15. data/lib/copy_tuner_client/copyray_middleware.rb +31 -24
  16. data/lib/copy_tuner_client/dotted_hash.rb +7 -7
  17. data/lib/copy_tuner_client/engine.rb +4 -6
  18. data/lib/copy_tuner_client/helper_extension.rb +58 -54
  19. data/lib/copy_tuner_client/i18n_backend.rb +12 -14
  20. data/lib/copy_tuner_client/i18n_compat.rb +2 -1
  21. data/lib/copy_tuner_client/poller.rb +3 -4
  22. data/lib/copy_tuner_client/prefixed_logger.rb +13 -12
  23. data/lib/copy_tuner_client/process_guard.rb +29 -26
  24. data/lib/copy_tuner_client/queue_with_timeout.rb +29 -19
  25. data/lib/copy_tuner_client/rails.rb +9 -8
  26. data/lib/copy_tuner_client/request_sync.rb +26 -24
  27. data/lib/copy_tuner_client/simple_form_extention.rb +10 -6
  28. data/lib/copy_tuner_client/translation_log.rb +10 -5
  29. data/lib/copy_tuner_client/version.rb +1 -1
  30. data/lib/copy_tuner_client.rb +4 -8
  31. data/lib/tasks/copy_tuner_client_tasks.rake +14 -16
  32. data/skills/copy-tuner-to-locales-migrate-prefix/scripts/migrate_prefix.rb +14 -7
  33. data/skills/copy-tuner-to-t-migrate/scripts/migrate_tt.rb +19 -17
  34. data/spec/copy_tuner_client/cache_spec.rb +63 -57
  35. data/spec/copy_tuner_client/client_spec.rb +82 -81
  36. data/spec/copy_tuner_client/configuration_spec.rb +223 -222
  37. data/spec/copy_tuner_client/copyray/marker_spec.rb +2 -1
  38. data/spec/copy_tuner_client/copyray/rewriter_spec.rb +15 -10
  39. data/spec/copy_tuner_client/copyray_middleware_spec.rb +9 -6
  40. data/spec/copy_tuner_client/copyray_spec.rb +8 -8
  41. data/spec/copy_tuner_client/dotted_hash_spec.rb +33 -33
  42. data/spec/copy_tuner_client/helper_extension_spec.rb +47 -44
  43. data/spec/copy_tuner_client/i18n_backend_spec.rb +144 -143
  44. data/spec/copy_tuner_client/poller_spec.rb +25 -24
  45. data/spec/copy_tuner_client/prefixed_logger_spec.rb +15 -12
  46. data/spec/copy_tuner_client/process_guard_spec.rb +27 -27
  47. data/spec/copy_tuner_client/request_sync_spec.rb +51 -58
  48. data/spec/copy_tuner_client/translation_log_spec.rb +38 -24
  49. data/spec/copy_tuner_client_spec.rb +5 -6
  50. data/spec/support/client_spec_helpers.rb +1 -1
  51. data/spec/support/defines_constants.rb +3 -34
  52. data/spec/support/fake_client.rb +1 -3
  53. data/spec/support/fake_copy_tuner_app.rb +54 -62
  54. data/spec/support/fake_html_safe_string.rb +2 -3
  55. data/spec/support/fake_logger.rb +22 -21
  56. data/spec/support/fake_passenger.rb +4 -6
  57. data/spec/support/fake_unicorn.rb +2 -4
  58. data/spec/support/middleware_stack.rb +3 -3
  59. data/spec/support/writing_cache.rb +4 -4
  60. metadata +1 -1
@@ -1,33 +1,32 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CopyTunerClient::Poller do
4
- POLLING_DELAY = 0.5
5
-
6
4
  let(:client) { FakeClient.new }
7
- let(:cache) { CopyTunerClient::Cache.new(client, :logger => FakeLogger.new) }
5
+ let(:cache) { CopyTunerClient::Cache.new(client, logger: FakeLogger.new) }
6
+ let!(:pollers) { [] }
7
+
8
+ def polling_delay
9
+ 0.5
10
+ end
8
11
 
9
12
  def build_poller(config = {})
10
13
  config[:logger] ||= FakeLogger.new
11
- config[:polling_delay] = POLLING_DELAY
14
+ config[:polling_delay] = polling_delay
12
15
  default_config = CopyTunerClient::Configuration.new.to_hash
13
16
  poller = CopyTunerClient::Poller.new(cache, default_config.update(config))
14
- @pollers << poller
17
+ pollers << poller
15
18
  poller
16
19
  end
17
20
 
18
21
  def wait_for_next_sync
19
- sleep(POLLING_DELAY * 3)
20
- end
21
-
22
- before do
23
- @pollers = []
22
+ sleep(polling_delay * 3)
24
23
  end
25
24
 
26
25
  after do
27
- @pollers.each { |poller| poller.stop }
26
+ pollers.each(&:stop)
28
27
  end
29
28
 
30
- it "it polls after being started" do
29
+ it 'polls after being started' do
31
30
  poller = build_poller
32
31
  poller.start
33
32
 
@@ -37,8 +36,8 @@ describe CopyTunerClient::Poller do
37
36
  expect(cache['test.key']).to eq('value')
38
37
  end
39
38
 
40
- it "it doesn't poll before being started" do
41
- poller = build_poller
39
+ it "doesn't poll before being started" do
40
+ build_poller
42
41
  client['test.key'] = 'value'
43
42
 
44
43
  wait_for_next_sync
@@ -46,7 +45,7 @@ describe CopyTunerClient::Poller do
46
45
  expect(cache['test.key']).to be_nil
47
46
  end
48
47
 
49
- it "stops polling when stopped" do
48
+ it 'stops polling when stopped' do
50
49
  poller = build_poller
51
50
 
52
51
  poller.start
@@ -58,12 +57,12 @@ describe CopyTunerClient::Poller do
58
57
  expect(cache['test.key']).to be_nil
59
58
  end
60
59
 
61
- it "stops polling with an invalid api key" do
62
- failure = "server is napping"
60
+ it 'stops polling with an invalid api key' do
61
+ failure = 'server is napping'
63
62
  logger = FakeLogger.new
64
63
 
65
- expect(cache).to receive(:download).and_raise(CopyTunerClient::InvalidApiKey.new(failure))
66
- poller = build_poller(:logger => logger)
64
+ allow(cache).to receive(:download).and_raise(CopyTunerClient::InvalidApiKey.new(failure))
65
+ poller = build_poller(logger:)
67
66
 
68
67
  cache['upload.key'] = 'upload'
69
68
  poller.start
@@ -78,20 +77,22 @@ describe CopyTunerClient::Poller do
78
77
  end
79
78
 
80
79
  it "logs an error if the background thread can't start" do
81
- expect(Thread).to receive(:new).and_return(nil)
80
+ allow(Thread).to receive(:new).and_return(nil)
82
81
  logger = FakeLogger.new
83
82
 
84
- build_poller(:logger => logger).start
83
+ build_poller(logger:).start
85
84
 
86
85
  expect(logger).to have_entry(:error, "Couldn't start poller thread")
87
86
  end
88
87
 
89
- it "flushes the log when polling" do
88
+ it 'flushes the log when polling' do
90
89
  logger = FakeLogger.new
91
- expect(logger).to receive(:flush).at_least(:once)
90
+ allow(logger).to receive(:flush)
92
91
 
93
- build_poller(:logger => logger).start
92
+ build_poller(logger:).start
94
93
 
95
94
  wait_for_next_sync
95
+
96
+ expect(logger).to have_received(:flush).at_least(:once)
96
97
  end
97
98
  end
@@ -1,35 +1,38 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CopyTunerClient::PrefixedLogger do
4
+ subject(:prefixed_logger) { described_class.new(prefix, output_logger) }
5
+
4
6
  let(:output_logger) { FakeLogger.new }
5
- let(:prefix) { "** NOTICE:" }
7
+ let(:prefix) { '** NOTICE:' }
6
8
  let(:thread_info) { "[P:#{Process.pid}] [T:#{Thread.current.object_id}]" }
7
- subject { CopyTunerClient::PrefixedLogger.new(prefix, output_logger) }
8
9
 
9
- it "provides the prefix" do
10
- expect(subject.prefix).to eq(prefix)
10
+ it 'provides the prefix' do
11
+ expect(prefixed_logger.prefix).to eq(prefix)
11
12
  end
12
13
 
13
- it "provides the logger" do
14
- expect(subject.original_logger).to eq(output_logger)
14
+ it 'provides the logger' do
15
+ expect(prefixed_logger.original_logger).to eq(output_logger)
15
16
  end
16
17
 
17
- [:debug, :info, :warn, :error, :fatal].each do |level|
18
+ %i[debug info warn error fatal].each do |level|
18
19
  it "prefixes #{level} log messages" do
19
20
  message = 'hello'
20
- subject.send(level, message)
21
+ prefixed_logger.public_send(level, message)
21
22
 
22
23
  expect(output_logger).to have_entry(level, "#{prefix} #{thread_info} #{message}")
23
24
  end
24
25
  end
25
26
 
26
- it "calls flush for a logger that responds to flush" do
27
- expect(output_logger).to receive(:flush)
27
+ it 'calls flush for a logger that responds to flush' do
28
+ allow(output_logger).to receive(:flush)
29
+
30
+ prefixed_logger.flush
28
31
 
29
- subject.flush
32
+ expect(output_logger).to have_received(:flush)
30
33
  end
31
34
 
32
35
  it "doesn't call flush for a logger that doesn't respond to flush" do
33
- expect { subject.flush }.not_to raise_error
36
+ expect { prefixed_logger.flush }.not_to raise_error
34
37
  end
35
38
  end
@@ -3,17 +3,14 @@ require 'spec_helper'
3
3
  describe CopyTunerClient::ProcessGuard do
4
4
  include DefinesConstants
5
5
 
6
- before do
7
- @original_process_name = $0
8
- end
6
+ let!(:original_process_name) { $PROGRAM_NAME }
7
+ let(:cache) { instance_double(CopyTunerClient::Cache, flush: nil) }
8
+ let(:poller) { instance_double(CopyTunerClient::Poller, start: nil) }
9
9
 
10
10
  after do
11
- $0 = @original_process_name
11
+ $0 = original_process_name
12
12
  end
13
13
 
14
- let(:cache) { double('cache', flush: nil) }
15
- let(:poller) { double('poller', start: nil) }
16
-
17
14
  def build_process_guard(options = {})
18
15
  preserve_exit_hook = options.delete(:preserve_exit_hook)
19
16
  options[:logger] ||= FakeLogger.new
@@ -23,67 +20,70 @@ describe CopyTunerClient::ProcessGuard do
23
20
  process_guard
24
21
  end
25
22
 
26
- it "starts polling from a worker process" do
27
- expect(poller).to receive(:start)
23
+ it 'starts polling from a worker process' do
28
24
  process_guard = build_process_guard
29
25
  process_guard.start
26
+
27
+ expect(poller).to have_received(:start)
30
28
  end
31
29
 
32
- it "registers passenger hooks from the passenger master" do
33
- expect(poller).not_to receive(:start)
30
+ it 'registers passenger hooks from the passenger master' do
34
31
  logger = FakeLogger.new
35
32
  passenger = define_constant('PhusionPassenger', FakePassenger.new)
36
33
  passenger.become_master
37
34
 
38
- process_guard = build_process_guard(:logger => logger)
35
+ process_guard = build_process_guard(logger:)
39
36
  process_guard.start
40
37
 
41
- expect(logger).to have_entry(:info, "Registered Phusion Passenger fork hook")
38
+ expect(poller).not_to have_received(:start)
39
+ expect(logger).to have_entry(:info, 'Registered Phusion Passenger fork hook')
42
40
  end
43
41
 
44
- it "starts polling from a passenger worker" do
45
- expect(poller).to receive(:start)
42
+ it 'starts polling from a passenger worker' do
46
43
  logger = FakeLogger.new
47
44
  passenger = define_constant('PhusionPassenger', FakePassenger.new)
48
45
  passenger.become_master
49
- process_guard = build_process_guard(:logger => logger)
46
+ process_guard = build_process_guard(logger:)
50
47
 
51
48
  process_guard.start
52
49
  passenger.spawn
50
+
51
+ expect(poller).to have_received(:start)
53
52
  end
54
53
 
55
- it "registers unicorn hooks from the unicorn master" do
56
- expect(poller).not_to receive(:start)
54
+ it 'registers unicorn hooks from the unicorn master' do
57
55
  logger = FakeLogger.new
58
56
  define_constant('Unicorn', Module.new)
59
57
  http_server = Class.new(FakeUnicornServer)
60
58
  unicorn = define_constant('Unicorn::HttpServer', http_server).new
61
59
  unicorn.become_master
62
60
 
63
- process_guard = build_process_guard(:logger => logger)
61
+ process_guard = build_process_guard(logger:)
64
62
  process_guard.start
65
63
 
66
- expect(logger).to have_entry(:info, "Registered Unicorn fork hook")
64
+ expect(poller).not_to have_received(:start)
65
+ expect(logger).to have_entry(:info, 'Registered Unicorn fork hook')
67
66
  end
68
67
 
69
- it "starts polling from a unicorn worker" do
70
- expect(poller).to receive(:start)
68
+ it 'starts polling from a unicorn worker' do
71
69
  logger = FakeLogger.new
72
70
  define_constant('Unicorn', Module.new)
73
71
  http_server = Class.new(FakeUnicornServer)
74
72
  unicorn = define_constant('Unicorn::HttpServer', http_server).new
75
73
  unicorn.become_master
76
- process_guard = build_process_guard(:logger => logger)
74
+ process_guard = build_process_guard(logger:)
77
75
 
78
76
  process_guard.start
79
77
  unicorn.spawn
78
+
79
+ expect(poller).to have_received(:start)
80
80
  end
81
81
 
82
- # FIXME: ruby@2.7以降で失敗するようになっているがテストコードの問題っぽいのでスキップしている
83
- xit "flushes when the process terminates" do
82
+ it 'flushes when the process terminates' do
84
83
  cache = WritingCache.new
85
- pid = fork do
86
- process_guard = build_process_guard(cache: cache, preserve_exit_hook: true)
84
+ FileUtils.rm_f(File.join(PROJECT_ROOT, 'tmp', 'written_cache'))
85
+ fork do
86
+ process_guard = build_process_guard(cache:, preserve_exit_hook: true)
87
87
  process_guard.start
88
88
  exit
89
89
  end
@@ -4,80 +4,73 @@ describe CopyTunerClient::RequestSync do
4
4
  let(:poller) { {} }
5
5
  let(:cache) { {} }
6
6
  let(:response) { 'response' }
7
- let(:env) { 'env' }
8
- let(:app) { double('app', :call => response) }
7
+ let(:app) { double('app', call: response) }
8
+
9
9
  before do
10
- allow(cache).to receive_messages(:flush => nil, :download => nil)
10
+ allow(cache).to receive_messages(flush: nil, download: nil)
11
11
  allow(poller).to receive(:start_sync).and_return(nil)
12
12
  end
13
- subject { CopyTunerClient::RequestSync.new(app, :poller => poller, :cache => cache, :interval => 0) }
14
13
 
15
- it "invokes the upstream app" do
16
- expect(app).to receive(:call).with(env)
17
- result = subject.call(env)
18
- expect(result).to eq(response)
19
- end
20
- end
14
+ context 'interval 0 の場合' do
15
+ subject(:request_sync) { described_class.new(app, poller:, cache:, interval: 0) }
21
16
 
22
- describe CopyTunerClient::RequestSync, 'serving assets' do
23
- let(:env) do
24
- { "PATH_INFO" => '/assets/choper.png' }
25
- end
26
- let(:poller) { {} }
27
- let(:cache) { {} }
28
- let(:response) { 'response' }
29
- let(:app) { double('app', :call => response) }
30
- before do
31
- allow(cache).to receive_messages(:flush => nil, :download => nil)
32
- allow(poller).to receive(:start_sync).and_return(nil)
33
- end
34
- subject { CopyTunerClient::RequestSync.new(app, :poller => poller, :cache => cache, :interval => 0) }
17
+ let(:env) { 'env' }
35
18
 
36
- it "don't start sync" do
37
- expect(cache).to receive(:download).once
38
- subject.call(env)
39
- expect(poller).not_to receive(:start_sync)
40
- subject.call(env)
19
+ it 'invokes the upstream app' do
20
+ result = request_sync.call(env)
21
+ expect(app).to have_received(:call).with(env)
22
+ expect(result).to eq(response)
23
+ end
41
24
  end
42
- end
43
25
 
44
- describe CopyTunerClient::RequestSync do
45
- let(:poller) { {} }
46
- let(:cache) { {} }
47
- let(:response) { 'response' }
48
- let(:env) { 'env' }
49
- let(:app) { double('app', :call => response) }
50
- subject { CopyTunerClient::RequestSync.new(app, :poller => poller, :cache => cache, :interval => 10) }
51
- before do
52
- allow(cache).to receive_messages(:flush => nil, :download => nil)
53
- allow(poller).to receive(:start_sync).and_return(nil)
54
- end
26
+ context 'when serving assets' do
27
+ subject(:request_sync) { described_class.new(app, poller:, cache:, interval: 0) }
55
28
 
56
- context "first request" do
57
- it "download" do
58
- expect(cache).to receive(:download).once
59
- subject.call(env)
29
+ let(:env) do
30
+ { 'PATH_INFO' => '/assets/choper.png' }
60
31
  end
61
- end
62
32
 
63
- context 'in interval request' do
64
- it "does not start sync for the second time" do
65
- expect(cache).to receive(:download).once
66
- subject.call(env)
33
+ it "don't start sync" do
34
+ request_sync.call(env)
35
+ request_sync.call(env)
67
36
 
68
- expect(poller).not_to receive(:start_sync)
69
- subject.call(env)
37
+ expect(cache).to have_received(:download).once
38
+ expect(poller).not_to have_received(:start_sync)
70
39
  end
71
40
  end
72
41
 
73
- context 'over interval request' do
74
- it "start sync for the second time" do
75
- expect(cache).to receive(:download).once
76
- subject.call(env)
42
+ context 'interval が 10 の場合' do
43
+ subject(:request_sync) { described_class.new(app, poller:, cache:, interval: 10) }
44
+
45
+ let(:env) { 'env' }
46
+
47
+ context 'first request' do
48
+ it 'download' do
49
+ request_sync.call(env)
50
+ expect(cache).to have_received(:download).once
51
+ end
52
+ end
53
+
54
+ context 'in interval request' do
55
+ it 'does not start sync for the second time' do
56
+ request_sync.call(env)
57
+ request_sync.call(env)
58
+
59
+ expect(cache).to have_received(:download).once
60
+ expect(poller).not_to have_received(:start_sync)
61
+ end
62
+ end
63
+
64
+ context 'over interval request' do
65
+ it 'start sync for the second time' do
66
+ request_sync.call(env)
67
+
68
+ request_sync.last_synced = Time.now - 60
69
+ request_sync.call(env)
77
70
 
78
- expect(poller).to receive(:start_sync).once
79
- subject.last_synced = Time.now - 60
80
- subject.call(env)
71
+ expect(cache).to have_received(:download).once
72
+ expect(poller).to have_received(:start_sync).once
73
+ end
81
74
  end
82
75
  end
83
76
  end
@@ -5,46 +5,60 @@ describe CopyTunerClient::TranslationLog do
5
5
  before { described_class.clear }
6
6
 
7
7
  describe '.add' do
8
- context 'when initialized' do
9
- it 'records the key' do
8
+ context '初期化済みかつキーが local_first_key_regexp にマッチする場合' do
9
+ before { CopyTunerClient.configuration.local_first_key_regexp = /\Aviews\./ }
10
+
11
+ it 'マッチしたキーを記録しないこと' do
12
+ described_class.add('views.foo', 'Hello')
13
+ expect(described_class.translations).to be_empty
14
+ end
15
+
16
+ it 'マッチしないキーは記録すること' do
17
+ described_class.add('messages.greeting', 'Hi')
18
+ expect(described_class.translations).to eq('messages.greeting' => 'Hi')
19
+ end
20
+ end
21
+
22
+ context '初期化済みかつ local_first_key_regexp が未設定の場合' do
23
+ it 'キーを記録すること' do
10
24
  described_class.add('views.foo', 'Hello')
11
25
  expect(described_class.translations).to eq('views.foo' => 'Hello')
12
26
  end
13
27
 
14
- it 'does not overwrite an existing key' do
28
+ it '既存のキーを上書きしないこと' do
15
29
  described_class.add('views.foo', 'Hello')
16
30
  described_class.add('views.foo', 'World')
17
31
  expect(described_class.translations['views.foo']).to eq 'Hello'
18
32
  end
33
+ end
19
34
 
20
- context 'when the key matches local_first_key_regexp' do
21
- before { CopyTunerClient.configuration.local_first_key_regexp = /\Aviews\./ }
22
-
23
- it 'does not record the matching key' do
24
- described_class.add('views.foo', 'Hello')
25
- expect(described_class.translations).to be_empty
26
- end
35
+ context '未初期化の場合' do
36
+ before { Thread.current[:translations] = nil }
27
37
 
28
- it 'records keys that do not match' do
29
- described_class.add('messages.greeting', 'Hi')
30
- expect(described_class.translations).to eq('messages.greeting' => 'Hi')
31
- end
38
+ it 'キーを無視すること' do
39
+ described_class.add('views.foo', 'Hello')
40
+ expect(described_class.initialized?).to be false
32
41
  end
42
+ end
43
+ end
33
44
 
34
- context 'when local_first_key_regexp is not set' do
35
- it 'records all keys' do
36
- described_class.add('views.foo', 'Hello')
37
- expect(described_class.translations).to eq('views.foo' => 'Hello')
38
- end
45
+ describe '.install_hook' do
46
+ # フック導入前後で I18n の特異クラスを復元し、他のテストへの副作用を防ぐ
47
+ around do |example|
48
+ original_singleton_methods = I18n.singleton_class.instance_methods(false)
49
+ example.run
50
+ (I18n.singleton_class.instance_methods(false) - original_singleton_methods).each do |method_name|
51
+ I18n.singleton_class.__send__(:remove_method, method_name)
39
52
  end
40
53
  end
41
54
 
42
- context 'when not initialized' do
43
- before { Thread.current[:translations] = nil }
55
+ context 'ミドルウェアが有効な場合' do
56
+ before { allow(CopyTunerClient.configuration).to receive(:enable_middleware?).and_return(true) }
44
57
 
45
- it 'ignores the key' do
46
- described_class.add('views.foo', 'Hello')
47
- expect(described_class.initialized?).to be false
58
+ it 'エラーを発生させずに I18n.translate をフックすること' do
59
+ expect { described_class.install_hook }.not_to raise_error
60
+ expect(I18n.translate(:hello, default: 'Hello')).to eq 'Hello'
61
+ expect(described_class.translations).to have_key('hello')
48
62
  end
49
63
  end
50
64
  end
@@ -1,18 +1,17 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe CopyTunerClient do
4
-
5
4
  before do
6
- allow(CopyTunerClient.configuration).to receive_messages(cache: 'cache', client: 'client')
5
+ allow(described_class.configuration).to receive_messages(cache: 'cache', client: 'client')
7
6
  end
8
7
 
9
8
  it 'delegates cache to the configuration object' do
10
- expect(CopyTunerClient.configuration).to receive(:cache).once
11
- expect(CopyTunerClient.cache).to eq('cache')
9
+ expect(described_class.cache).to eq('cache')
10
+ expect(described_class.configuration).to have_received(:cache).once
12
11
  end
13
12
 
14
13
  it 'delegates client to the configuration object' do
15
- expect(CopyTunerClient.configuration).to receive(:client).once
16
- expect(CopyTunerClient.client).to eq('client')
14
+ expect(described_class.client).to eq('client')
15
+ expect(described_class.configuration).to have_received(:client).once
17
16
  end
18
17
  end
@@ -1,7 +1,7 @@
1
1
  module ClientSpecHelpers
2
2
  def reset_config
3
3
  CopyTunerClient.configuration = nil
4
- CopyTunerClient.configure(false) do |config|
4
+ CopyTunerClient.configure(apply: false) do |config|
5
5
  config.api_key = 'abc123'
6
6
  config.s3_host = 'copy-tuner.com'
7
7
  end
@@ -1,44 +1,13 @@
1
1
  module DefinesConstants
2
- def self.included(example_group)
3
- super
4
- example_group.class_eval do
5
- before { @defined_constants = [] }
6
- after { undefine_constants }
7
- end
8
- end
9
-
10
- def define_class(class_name, base = Object, &block)
2
+ def define_class(class_name, base = Object, &)
11
3
  class_name = class_name.to_s.camelize
12
4
  klass = Class.new(base)
13
5
  define_constant(class_name, klass)
14
- klass.class_eval(&block) if block_given?
6
+ klass.class_eval(&) if block_given?
15
7
  klass
16
8
  end
17
9
 
18
10
  def define_constant(path, value)
19
- parse_constant(path) do |parent, name|
20
- parent.const_set(name, value)
21
- end
22
-
23
- @defined_constants << path
24
- value
25
- end
26
-
27
- def parse_constant(path)
28
- parent_names = path.split('::')
29
- name = parent_names.pop
30
- parent = parent_names.inject(Object) do |ref, child_name|
31
- ref.const_get(child_name)
32
- end
33
- yield(parent, name)
34
- end
35
-
36
- def undefine_constants
37
- @defined_constants.reverse.each do |path|
38
- parse_constant(path) do |parent, name|
39
- parent.send(:remove_const, name)
40
- end
41
- end
11
+ stub_const(path, value)
42
12
  end
43
13
  end
44
-
@@ -58,8 +58,6 @@ class FakeClient
58
58
  end
59
59
 
60
60
  def raise_error_if_present
61
- if error
62
- raise error
63
- end
61
+ raise error if error
64
62
  end
65
63
  end