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.
- checksums.yaml +4 -4
- data/.gitignore +5 -0
- data/.rubocop.yml +46 -1
- data/CLAUDE.md +1 -0
- data/Gemfile +1 -0
- data/copy_tuner_client.gemspec +3 -3
- data/gemfiles/8.0.gemfile +3 -3
- data/gemfiles/8.1.gemfile +3 -3
- data/gemfiles/main.gemfile +3 -3
- data/lib/copy_tuner_client/cache.rb +34 -27
- data/lib/copy_tuner_client/client.rb +35 -23
- data/lib/copy_tuner_client/configuration.rb +62 -40
- data/lib/copy_tuner_client/copyray/rewriter.rb +1 -1
- data/lib/copy_tuner_client/copyray.rb +1 -0
- data/lib/copy_tuner_client/copyray_middleware.rb +31 -24
- data/lib/copy_tuner_client/dotted_hash.rb +7 -7
- data/lib/copy_tuner_client/engine.rb +4 -6
- data/lib/copy_tuner_client/helper_extension.rb +58 -54
- data/lib/copy_tuner_client/i18n_backend.rb +12 -14
- data/lib/copy_tuner_client/i18n_compat.rb +2 -1
- data/lib/copy_tuner_client/poller.rb +3 -4
- data/lib/copy_tuner_client/prefixed_logger.rb +13 -12
- data/lib/copy_tuner_client/process_guard.rb +29 -26
- data/lib/copy_tuner_client/queue_with_timeout.rb +29 -19
- data/lib/copy_tuner_client/rails.rb +9 -8
- data/lib/copy_tuner_client/request_sync.rb +26 -24
- data/lib/copy_tuner_client/simple_form_extention.rb +10 -6
- data/lib/copy_tuner_client/translation_log.rb +10 -5
- data/lib/copy_tuner_client/version.rb +1 -1
- data/lib/copy_tuner_client.rb +4 -8
- data/lib/tasks/copy_tuner_client_tasks.rake +14 -16
- data/skills/copy-tuner-to-locales-migrate-prefix/scripts/migrate_prefix.rb +14 -7
- data/skills/copy-tuner-to-t-migrate/scripts/migrate_tt.rb +19 -17
- data/spec/copy_tuner_client/cache_spec.rb +63 -57
- data/spec/copy_tuner_client/client_spec.rb +82 -81
- data/spec/copy_tuner_client/configuration_spec.rb +223 -222
- data/spec/copy_tuner_client/copyray/marker_spec.rb +2 -1
- data/spec/copy_tuner_client/copyray/rewriter_spec.rb +15 -10
- data/spec/copy_tuner_client/copyray_middleware_spec.rb +9 -6
- data/spec/copy_tuner_client/copyray_spec.rb +8 -8
- data/spec/copy_tuner_client/dotted_hash_spec.rb +33 -33
- data/spec/copy_tuner_client/helper_extension_spec.rb +47 -44
- data/spec/copy_tuner_client/i18n_backend_spec.rb +144 -143
- data/spec/copy_tuner_client/poller_spec.rb +25 -24
- data/spec/copy_tuner_client/prefixed_logger_spec.rb +15 -12
- data/spec/copy_tuner_client/process_guard_spec.rb +27 -27
- data/spec/copy_tuner_client/request_sync_spec.rb +51 -58
- data/spec/copy_tuner_client/translation_log_spec.rb +38 -24
- data/spec/copy_tuner_client_spec.rb +5 -6
- data/spec/support/client_spec_helpers.rb +1 -1
- data/spec/support/defines_constants.rb +3 -34
- data/spec/support/fake_client.rb +1 -3
- data/spec/support/fake_copy_tuner_app.rb +54 -62
- data/spec/support/fake_html_safe_string.rb +2 -3
- data/spec/support/fake_logger.rb +22 -21
- data/spec/support/fake_passenger.rb +4 -6
- data/spec/support/fake_unicorn.rb +2 -4
- data/spec/support/middleware_stack.rb +3 -3
- data/spec/support/writing_cache.rb +4 -4
- metadata +1 -1
|
@@ -14,8 +14,9 @@ describe CopyTunerClient::Copyray::Rewriter do
|
|
|
14
14
|
describe '.rewrite' do
|
|
15
15
|
# NOTE: rewrite は [html, skipped] を返すが、既存テストの大半は html だけを検証する。
|
|
16
16
|
# 1 回の呼び出しを let でメモ化して共有し、result は html、skipped は 2 要素目を指す。
|
|
17
|
-
let(:rewritten) { described_class.rewrite(html) }
|
|
18
17
|
subject(:result) { rewritten.first }
|
|
18
|
+
|
|
19
|
+
let(:rewritten) { described_class.rewrite(html) }
|
|
19
20
|
let(:skipped) { rewritten.last }
|
|
20
21
|
|
|
21
22
|
context '要素直下の単純なテキストノード' do
|
|
@@ -189,10 +190,11 @@ describe CopyTunerClient::Copyray::Rewriter do
|
|
|
189
190
|
end
|
|
190
191
|
|
|
191
192
|
it 'logger.warn で例外内容を記録する' do
|
|
192
|
-
logger =
|
|
193
|
+
logger = instance_double(Logger)
|
|
193
194
|
allow(CopyTunerClient.configuration).to receive(:logger).and_return(logger)
|
|
194
|
-
|
|
195
|
+
allow(logger).to receive(:warn)
|
|
195
196
|
result
|
|
197
|
+
expect(logger).to have_received(:warn).with(/Rewriter failed.*RuntimeError.*boom/)
|
|
196
198
|
end
|
|
197
199
|
|
|
198
200
|
it 'logger が nil でもフォールバックが落ちない' do
|
|
@@ -203,18 +205,21 @@ describe CopyTunerClient::Copyray::Rewriter do
|
|
|
203
205
|
end
|
|
204
206
|
|
|
205
207
|
context 'fragment: true(turbo stream などの HTML 断片)' do
|
|
206
|
-
|
|
207
|
-
|
|
208
|
+
subject(:fragment_result) { described_class.rewrite(html, fragment: true).first }
|
|
209
|
+
|
|
210
|
+
let(:html) do
|
|
211
|
+
%(<turbo-stream action="replace" target="x"><template><p>#{marker('a.b')}Hello</p></template></turbo-stream>)
|
|
212
|
+
end
|
|
208
213
|
|
|
209
214
|
it 'html/body ラッパを足さず断片のまま返す' do
|
|
210
|
-
expect(
|
|
211
|
-
expect(
|
|
212
|
-
expect(
|
|
215
|
+
expect(fragment_result).not_to include('<html>')
|
|
216
|
+
expect(fragment_result).not_to include('<body>')
|
|
217
|
+
expect(fragment_result).to start_with('<turbo-stream')
|
|
213
218
|
end
|
|
214
219
|
|
|
215
220
|
it 'template 内の要素に data-copyray-key を付与しトークンを除去する' do
|
|
216
|
-
expect(
|
|
217
|
-
expect(
|
|
221
|
+
expect(fragment_result).to include('data-copyray-key="a.b"')
|
|
222
|
+
expect(fragment_result).not_to match CopyTunerClient::Copyray::Marker::SCAN_REGEXP
|
|
218
223
|
end
|
|
219
224
|
end
|
|
220
225
|
|
|
@@ -8,12 +8,11 @@ describe CopyTunerClient::CopyrayMiddleware do
|
|
|
8
8
|
CopyTunerClient::Copyray::Marker.encode(key)
|
|
9
9
|
end
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
subject(:middleware) { described_class.new(app) }
|
|
12
|
+
|
|
12
13
|
let(:app) { ->(_env) { [status, headers, [body]] } }
|
|
13
14
|
let(:status) { 200 }
|
|
14
15
|
|
|
15
|
-
subject(:middleware) { described_class.new(app) }
|
|
16
|
-
|
|
17
16
|
before do
|
|
18
17
|
CopyTunerClient.configure do |configuration|
|
|
19
18
|
configuration.project_id = 1
|
|
@@ -25,6 +24,7 @@ describe CopyTunerClient::CopyrayMiddleware do
|
|
|
25
24
|
end
|
|
26
25
|
|
|
27
26
|
context 'マーカートークンを含む HTML レスポンスのとき' do
|
|
27
|
+
let(:headers) { { 'Content-Type' => 'text/html' } }
|
|
28
28
|
let(:body) { "<html><body><p>#{marker('a.b')}Hello</p></body></html>" }
|
|
29
29
|
|
|
30
30
|
it 'マーカーを data-copyray-key 属性に書き換え、トークンを除去する' do
|
|
@@ -37,13 +37,16 @@ describe CopyTunerClient::CopyrayMiddleware do
|
|
|
37
37
|
|
|
38
38
|
it '書き換え後のボディから Content-Length を再計算する' do
|
|
39
39
|
_status, out_headers, response = middleware.call({})
|
|
40
|
-
|
|
40
|
+
expected_length = response.join.bytesize.to_s
|
|
41
|
+
expect(out_headers['Content-Length']).to eq expected_length
|
|
41
42
|
end
|
|
42
43
|
end
|
|
43
44
|
|
|
44
45
|
context 'turbo stream レスポンスのとき' do
|
|
45
46
|
let(:headers) { { 'Content-Type' => 'text/vnd.turbo-stream.html' } }
|
|
46
|
-
let(:body)
|
|
47
|
+
let(:body) do
|
|
48
|
+
%(<turbo-stream action="replace" target="x"><template><p>#{marker('a.b')}Hello</p></template></turbo-stream>)
|
|
49
|
+
end
|
|
47
50
|
|
|
48
51
|
before do
|
|
49
52
|
# NOTE: append_js のトップレベル no-op スタブを外し、turbo stream では JS を挿入しないことを検証する。
|
|
@@ -89,7 +92,7 @@ describe CopyTunerClient::CopyrayMiddleware do
|
|
|
89
92
|
# NOTE: append_js は private かつ Rails の view ヘルパー(javascript_tag 等)に依存する。
|
|
90
93
|
# トップレベルの no-op スタブを外して実体を呼び、ヘルパーは渡された script 本文をそのまま
|
|
91
94
|
# 返す最小フェイクに差し替えて、window.CopyTuner に keysSkipped が埋まることだけ検証する。
|
|
92
|
-
subject(:script) { middleware.__send__(:append_js, '<html><body></body></html>', nil, skipped:
|
|
95
|
+
subject(:script) { middleware.__send__(:append_js, '<html><body></body></html>', nil, skipped:) }
|
|
93
96
|
|
|
94
97
|
let(:fake_helpers) do
|
|
95
98
|
Class.new {
|
|
@@ -3,7 +3,7 @@ require 'copy_tuner_client/copyray'
|
|
|
3
3
|
|
|
4
4
|
describe CopyTunerClient::Copyray do
|
|
5
5
|
describe '.augment_template' do
|
|
6
|
-
subject {
|
|
6
|
+
subject(:augmented) { described_class.augment_template(source, key) }
|
|
7
7
|
|
|
8
8
|
let(:key) { 'en.test.key' }
|
|
9
9
|
|
|
@@ -18,11 +18,11 @@ describe CopyTunerClient::Copyray do
|
|
|
18
18
|
let(:source) { FakeHtmlSafeString.new('<b>Hello</b>').html_safe }
|
|
19
19
|
|
|
20
20
|
it 'keeps the html_safe flag so the translation is not re-escaped' do
|
|
21
|
-
|
|
21
|
+
expect(augmented).to be_html_safe
|
|
22
22
|
end
|
|
23
23
|
|
|
24
24
|
it 'prepends the visible marker token without escaping' do
|
|
25
|
-
|
|
25
|
+
expect(augmented).to eq '⟦CT:en.test.key⟧<b>Hello</b>'
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
|
|
@@ -30,22 +30,22 @@ describe CopyTunerClient::Copyray do
|
|
|
30
30
|
let(:source) { FakeHtmlSafeString.new('Hello & <World>') }
|
|
31
31
|
|
|
32
32
|
it 'prepends the marker but keeps the source non html_safe so ActionView still escapes the body' do
|
|
33
|
-
|
|
34
|
-
|
|
33
|
+
expect(augmented).to eq '⟦CT:en.test.key⟧Hello & <World>'
|
|
34
|
+
expect(augmented).not_to be_html_safe
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
37
|
|
|
38
38
|
context 'when the key matches local_first_key_regexp' do
|
|
39
|
-
let(:
|
|
39
|
+
let(:local_first_key) { 'views.foo' }
|
|
40
40
|
|
|
41
41
|
before { CopyTunerClient.configuration.local_first_key_regexp = /\Aviews\./ }
|
|
42
42
|
|
|
43
43
|
it 'does not inject the marker into a plain source' do
|
|
44
|
-
expect(
|
|
44
|
+
expect(described_class.augment_template('Hello', local_first_key)).to eq 'Hello'
|
|
45
45
|
end
|
|
46
46
|
|
|
47
47
|
it 'does not inject the marker into an html_safe source' do
|
|
48
|
-
expect(
|
|
48
|
+
expect(described_class.augment_template('Hello'.html_safe, local_first_key)).to eq 'Hello'
|
|
49
49
|
end
|
|
50
50
|
end
|
|
51
51
|
end
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
require 'spec_helper'
|
|
2
2
|
|
|
3
3
|
describe CopyTunerClient::DottedHash do
|
|
4
|
-
describe
|
|
5
|
-
subject {
|
|
4
|
+
describe '.to_h' do
|
|
5
|
+
subject(:converted_hash) { described_class.to_h(dotted_hash) }
|
|
6
6
|
|
|
7
7
|
context '空のキーの場合' do
|
|
8
8
|
let(:dotted_hash) { {} }
|
|
@@ -22,7 +22,7 @@ describe CopyTunerClient::DottedHash do
|
|
|
22
22
|
it { is_expected.to eq({ 'key' => 'test value', 'other_key' => 'other value' }) }
|
|
23
23
|
end
|
|
24
24
|
|
|
25
|
-
context
|
|
25
|
+
context '複数階層のblurbキーの場合' do
|
|
26
26
|
let(:dotted_hash) do
|
|
27
27
|
{
|
|
28
28
|
'en.test.key' => 'en test value',
|
|
@@ -31,24 +31,24 @@ describe CopyTunerClient::DottedHash do
|
|
|
31
31
|
}
|
|
32
32
|
end
|
|
33
33
|
|
|
34
|
-
it
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
34
|
+
it '正しくネストされたハッシュに変換されること' do
|
|
35
|
+
expect(converted_hash).to eq({
|
|
36
|
+
'en' => {
|
|
37
|
+
'test' => {
|
|
38
|
+
'key' => 'en test value',
|
|
39
|
+
'other_key' => 'en other test value',
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
'fr' => {
|
|
43
|
+
'test' => {
|
|
44
|
+
'key' => 'fr test value',
|
|
45
|
+
},
|
|
46
|
+
},
|
|
47
|
+
})
|
|
48
48
|
end
|
|
49
49
|
end
|
|
50
50
|
|
|
51
|
-
context
|
|
51
|
+
context 'キーの競合がある場合' do
|
|
52
52
|
let(:dotted_hash) do
|
|
53
53
|
{
|
|
54
54
|
'en.test' => 'invalid value',
|
|
@@ -62,7 +62,7 @@ describe CopyTunerClient::DottedHash do
|
|
|
62
62
|
# NOTE: number.*.format 配下のキー(precision 等)は I18nBackend の local_first_key? ガードで
|
|
63
63
|
# tree_cache をバイパスしローカル YAML 優先になるため、ここで型変換せず文字列のまま保持する。
|
|
64
64
|
# (number_to_currency が壊れないことは i18n_backend_spec の number ローカル優先テストで担保)
|
|
65
|
-
context
|
|
65
|
+
context 'number.*.format 配下の値を含む場合' do
|
|
66
66
|
let(:dotted_hash) do
|
|
67
67
|
{
|
|
68
68
|
'en.number.currency.format.precision' => '2',
|
|
@@ -70,19 +70,19 @@ describe CopyTunerClient::DottedHash do
|
|
|
70
70
|
}
|
|
71
71
|
end
|
|
72
72
|
|
|
73
|
-
it
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
73
|
+
it '型変換せず値を文字列のまま保持する' do
|
|
74
|
+
expect(converted_hash).to eq({
|
|
75
|
+
'en' => {
|
|
76
|
+
'number' => { 'currency' => { 'format' => { 'precision' => '2' } } },
|
|
77
|
+
'custom' => { 'precision' => 'custom_value' },
|
|
78
|
+
},
|
|
79
|
+
})
|
|
80
80
|
end
|
|
81
81
|
end
|
|
82
82
|
end
|
|
83
83
|
|
|
84
|
-
describe
|
|
85
|
-
subject {
|
|
84
|
+
describe '.conflict_keys' do
|
|
85
|
+
subject(:conflicts) { described_class.conflict_keys(dotted_hash) }
|
|
86
86
|
|
|
87
87
|
context '有効なキーの場合' do
|
|
88
88
|
let(:dotted_hash) do
|
|
@@ -106,11 +106,11 @@ describe CopyTunerClient::DottedHash do
|
|
|
106
106
|
}
|
|
107
107
|
end
|
|
108
108
|
|
|
109
|
-
it
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
109
|
+
it '競合するキーが正しく検出されること' do
|
|
110
|
+
expect(conflicts).to eq({
|
|
111
|
+
'ja.fuga.test' => %w[ja.fuga.test.hoge],
|
|
112
|
+
'ja.hoge.test' => %w[ja.hoge.test.fuga ja.hoge.test.hoge],
|
|
113
|
+
})
|
|
114
114
|
end
|
|
115
115
|
end
|
|
116
116
|
end
|
|
@@ -3,57 +3,59 @@ require 'copy_tuner_client/helper_extension'
|
|
|
3
3
|
require 'copy_tuner_client/copyray'
|
|
4
4
|
|
|
5
5
|
describe CopyTunerClient::HelperExtension do
|
|
6
|
-
|
|
7
|
-
# 単体 spec では require できないため、メソッドをスタブできる最小の入れ物だけ用意する。
|
|
8
|
-
module CopyTunerClient
|
|
9
|
-
module Rails
|
|
10
|
-
def self.controller_of_rails_engine?(_controller)
|
|
11
|
-
false
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
|
6
|
+
include DefinesConstants
|
|
15
7
|
|
|
16
8
|
# NOTE: request.format で描画フォーマットを判定するため、format を差し替えられる
|
|
17
9
|
# 最小のフェイク request / controller を用意する。mailer 判定は controller の型で行う。
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
type
|
|
21
|
-
|
|
10
|
+
def format_class
|
|
11
|
+
@format_class ||=
|
|
12
|
+
Struct.new(:type) do
|
|
13
|
+
def html?
|
|
14
|
+
type == :html
|
|
15
|
+
end
|
|
16
|
+
end
|
|
22
17
|
end
|
|
23
|
-
Request = Struct.new(:format)
|
|
24
|
-
Controller = Struct.new(:request)
|
|
25
|
-
|
|
26
|
-
module KeywordArgumentsHelper
|
|
27
|
-
attr_writer :controller
|
|
28
|
-
|
|
29
|
-
# NOTE: ActionView の TranslationHelper を模し、.html/_html キーのみ html_safe な訳文を返す。
|
|
30
|
-
# マーカーは平文・html_safe どちらにも注入されるが、html_safe フラグの引き継ぎを検証できるよう両方返し分ける。
|
|
31
|
-
def translate(key, **options)
|
|
32
|
-
source = "Hello, #{options[:name]}"
|
|
33
|
-
key.to_s.end_with?('.html', '_html') ? source.html_safe : source
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def controller
|
|
37
|
-
return @controller if defined?(@controller)
|
|
38
18
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
@controller = Controller.new(Request.new(Format.new(:html)))
|
|
42
|
-
end
|
|
19
|
+
def request_class
|
|
20
|
+
@request_class ||= Struct.new(:format)
|
|
43
21
|
end
|
|
44
22
|
|
|
45
|
-
|
|
46
|
-
|
|
23
|
+
def controller_class
|
|
24
|
+
@controller_class ||= Struct.new(:request)
|
|
47
25
|
end
|
|
48
26
|
|
|
49
|
-
|
|
27
|
+
# NOTE: hook_translation_helper は渡されたモジュール自体を破壊的に変更する(alias_method 等)ため、
|
|
28
|
+
# view に include するモジュールと hook_translation_helper に渡すモジュールは同一オブジェクトである必要がある。
|
|
29
|
+
def keyword_arguments_helper
|
|
30
|
+
@keyword_arguments_helper ||=
|
|
31
|
+
Module.new do
|
|
32
|
+
attr_accessor :controller
|
|
33
|
+
|
|
34
|
+
# NOTE: ActionView の TranslationHelper を模し、.html/_html キーのみ html_safe な訳文を返す。
|
|
35
|
+
# マーカーは平文・html_safe どちらにも注入されるが、html_safe フラグの引き継ぎを検証できるよう両方返し分ける。
|
|
36
|
+
define_method(:translate) do |key, **options|
|
|
37
|
+
source = "Hello, #{options[:name]}"
|
|
38
|
+
key.to_s.end_with?('.html', '_html') ? source.html_safe : source
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
50
42
|
|
|
51
|
-
|
|
43
|
+
# NOTE: 実 HTML 描画では controller が存在し request.format が html になるため、
|
|
44
|
+
# デフォルトはそれを再現した controller を持たせておく。
|
|
45
|
+
let(:view) do
|
|
46
|
+
Class.new.include(keyword_arguments_helper).new.tap do |v|
|
|
47
|
+
v.controller = controller_class.new(request_class.new(format_class.new(:html)))
|
|
48
|
+
end
|
|
49
|
+
end
|
|
52
50
|
|
|
53
51
|
before do
|
|
54
|
-
# NOTE:
|
|
55
|
-
#
|
|
56
|
-
|
|
52
|
+
# NOTE: helper_extension が参照する CopyTunerClient::Rails は engine への依存があり
|
|
53
|
+
# 単体 spec では require できず、controller_of_rails_engine? も ::Rails::Engine への
|
|
54
|
+
# 依存があり単体 spec では評価できないため、この spec の関心(注入ガード)に絞って
|
|
55
|
+
# 常に false を返すフェイクモジュールに差し替える。
|
|
56
|
+
fake_rails_module = Module.new { def self.controller_of_rails_engine?(_controller) = false }
|
|
57
|
+
define_constant('CopyTunerClient::Rails', fake_rails_module)
|
|
58
|
+
described_class.hook_translation_helper(keyword_arguments_helper, middleware_enabled: true)
|
|
57
59
|
end
|
|
58
60
|
|
|
59
61
|
it 'works with keyword argument method' do
|
|
@@ -82,7 +84,7 @@ describe CopyTunerClient::HelperExtension do
|
|
|
82
84
|
|
|
83
85
|
%i[json text csv pdf].each do |format|
|
|
84
86
|
it "does not inject the marker when request.format is :#{format}" do
|
|
85
|
-
view.controller =
|
|
87
|
+
view.controller = controller_class.new(request_class.new(format_class.new(format)))
|
|
86
88
|
expect(view.translate('some.key', name: 'World')).to eq 'Hello, World'
|
|
87
89
|
end
|
|
88
90
|
end
|
|
@@ -101,13 +103,13 @@ describe CopyTunerClient::HelperExtension do
|
|
|
101
103
|
end
|
|
102
104
|
|
|
103
105
|
it 'does not inject the marker when the controller has no request' do
|
|
104
|
-
view.controller =
|
|
106
|
+
view.controller = controller_class.new(nil)
|
|
105
107
|
expect(view.translate('some.key', name: 'World')).to eq 'Hello, World'
|
|
106
108
|
end
|
|
107
109
|
|
|
108
110
|
it 'does not raise when ActionMailer is not loaded' do
|
|
109
111
|
hide_const('ActionMailer::Base') if defined?(ActionMailer::Base)
|
|
110
|
-
view.controller =
|
|
112
|
+
view.controller = controller_class.new(request_class.new(format_class.new(:html)))
|
|
111
113
|
expect { view.translate('some.key', name: 'World') }.not_to raise_error
|
|
112
114
|
end
|
|
113
115
|
end
|
|
@@ -116,9 +118,10 @@ describe CopyTunerClient::HelperExtension do
|
|
|
116
118
|
# 維持されなければならない。注入ガードが初期値登録まで巻き添えで止めていないことを保証する。
|
|
117
119
|
context 'default value registration' do
|
|
118
120
|
it 'registers the default value even when the marker is not injected' do
|
|
119
|
-
view.controller =
|
|
120
|
-
|
|
121
|
+
view.controller = controller_class.new(request_class.new(format_class.new(:json)))
|
|
122
|
+
allow(I18n).to receive(:t)
|
|
121
123
|
view.translate('some.key', name: 'World', default: 'Default')
|
|
124
|
+
expect(I18n).to have_received(:t).with('some.key', hash_including(default: 'Default'))
|
|
122
125
|
end
|
|
123
126
|
end
|
|
124
127
|
end
|