i18nliner 0.2.4 → 0.3.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/Rakefile +8 -6
- data/lib/i18nliner/base.rb +26 -27
- data/lib/i18nliner/call_helpers.rb +42 -34
- data/lib/i18nliner/commands/basic_formatter.rb +2 -0
- data/lib/i18nliner/commands/check.rb +14 -14
- data/lib/i18nliner/commands/color_formatter.rb +2 -0
- data/lib/i18nliner/commands/dump.rb +6 -6
- data/lib/i18nliner/commands/generic_command.rb +4 -2
- data/lib/i18nliner/controller_scope.rb +2 -0
- data/lib/i18nliner/errors.rb +5 -4
- data/lib/i18nliner/erubi.rb +5 -4
- data/lib/i18nliner/erubis.rb +2 -0
- data/lib/i18nliner/extensions/controller.rb +8 -8
- data/lib/i18nliner/extensions/core.rb +16 -18
- data/lib/i18nliner/extensions/inferpolation.rb +11 -7
- data/lib/i18nliner/extensions/model.rb +11 -10
- data/lib/i18nliner/extensions/view.rb +13 -9
- data/lib/i18nliner/extractors/ruby_extractor.rb +18 -16
- data/lib/i18nliner/extractors/sexp_helper.rb +8 -5
- data/lib/i18nliner/extractors/translate_call.rb +31 -26
- data/lib/i18nliner/extractors/translation_hash.rb +10 -10
- data/lib/i18nliner/pre_processors/erb_pre_processor.rb +63 -49
- data/lib/i18nliner/processors/abstract_processor.rb +9 -4
- data/lib/i18nliner/processors/erb_processor.rb +10 -8
- data/lib/i18nliner/processors/ruby_processor.rb +13 -10
- data/lib/i18nliner/processors.rb +2 -0
- data/lib/i18nliner/railtie.rb +10 -10
- data/lib/i18nliner/reserved_keys.rb +2 -0
- data/lib/i18nliner/scope.rb +7 -9
- data/lib/i18nliner.rb +8 -6
- data/lib/tasks/i18nliner.rake +8 -7
- data/spec/fixtures/app/models/invalid.rb +2 -0
- data/spec/fixtures/app/models/valid.rb +2 -0
- data/spec/{commands → i18nliner/commands}/check_spec.rb +5 -6
- data/spec/{commands → i18nliner/commands}/dump_spec.rb +9 -10
- data/spec/{extensions → i18nliner/extensions}/controller_spec.rb +9 -8
- data/spec/{extensions → i18nliner/extensions}/core_spec.rb +45 -34
- data/spec/i18nliner/extensions/inferpolation_spec.rb +51 -0
- data/spec/i18nliner/extensions/model_spec.rb +31 -0
- data/spec/{extensions → i18nliner/extensions}/view_spec.rb +15 -13
- data/spec/{extractors → i18nliner/extractors}/ruby_extractor_spec.rb +24 -15
- data/spec/{extractors → i18nliner/extractors}/translate_call_spec.rb +73 -65
- data/spec/{extractors → i18nliner/extractors}/translation_hash_spec.rb +13 -12
- data/spec/{reserved_keys_spec.rb → i18nliner/i18n_spec.rb} +3 -1
- data/spec/{pre_processors → i18nliner/pre_processors}/erb_pre_processor_spec.rb +80 -77
- data/spec/i18nliner/processors/erb_processor_spec.rb +45 -0
- data/spec/i18nliner/processors/ruby_processor_spec.rb +27 -0
- metadata +58 -88
- data/spec/extensions/inferpolation_spec.rb +0 -49
- data/spec/extensions/model_spec.rb +0 -30
- data/spec/processors/erb_processor_spec.rb +0 -45
- data/spec/processors/ruby_processor_spec.rb +0 -28
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/base"
|
|
4
|
+
require "i18nliner/scope"
|
|
5
|
+
require "i18nliner/extractors/translate_call"
|
|
5
6
|
|
|
6
7
|
describe I18nliner::Extractors::TranslateCall do
|
|
7
8
|
def call(scope, *args)
|
|
@@ -9,62 +10,62 @@ describe I18nliner::Extractors::TranslateCall do
|
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
let(:no_scope) { I18nliner::Scope.new(nil) }
|
|
12
|
-
let(:scope) { I18nliner::Scope.new("foo", :
|
|
13
|
-
let(:erb_scope) { I18nliner::Scope.new(nil, :
|
|
13
|
+
let(:scope) { I18nliner::Scope.new("foo", auto: true, allow_relative: true) }
|
|
14
|
+
let(:erb_scope) { I18nliner::Scope.new(nil, remove_whitespace: true) }
|
|
14
15
|
|
|
15
16
|
describe "signature" do
|
|
16
17
|
it "should reject extra arguments" do
|
|
17
|
-
expect
|
|
18
|
+
expect do
|
|
18
19
|
call(no_scope, :key, "value", {}, :wat)
|
|
19
|
-
|
|
20
|
+
end.to raise_error(I18nliner::InvalidSignatureError)
|
|
20
21
|
end
|
|
21
22
|
|
|
22
23
|
it "should accept a valid key or default" do
|
|
23
|
-
expect
|
|
24
|
+
expect do
|
|
24
25
|
call(no_scope, "key", "value", {})
|
|
25
|
-
|
|
26
|
+
end.not_to raise_error
|
|
26
27
|
|
|
27
|
-
expect
|
|
28
|
+
expect do
|
|
28
29
|
call(no_scope, "key_or_value", {})
|
|
29
|
-
|
|
30
|
+
end.not_to raise_error
|
|
30
31
|
|
|
31
|
-
expect
|
|
32
|
+
expect do
|
|
32
33
|
call(no_scope, :key, {})
|
|
33
|
-
|
|
34
|
+
end.not_to raise_error
|
|
34
35
|
end
|
|
35
36
|
|
|
36
37
|
it "should require at least a key or default" do
|
|
37
|
-
expect
|
|
38
|
+
expect do
|
|
38
39
|
call(no_scope)
|
|
39
|
-
|
|
40
|
+
end.to raise_error(I18nliner::InvalidSignatureError)
|
|
40
41
|
end
|
|
41
42
|
|
|
42
43
|
it "should require a literal default" do
|
|
43
|
-
expect
|
|
44
|
+
expect do
|
|
44
45
|
call(no_scope, :key, Object.new)
|
|
45
|
-
|
|
46
|
+
end.to raise_error(I18nliner::InvalidSignatureError)
|
|
46
47
|
end
|
|
47
48
|
|
|
48
49
|
# for legacy calls, e.g. t :key, :default => "foo"
|
|
49
50
|
it "should allow the default to be specified in the options hash" do
|
|
50
|
-
call = call(no_scope, :key, :
|
|
51
|
+
call = call(no_scope, :key, default: "foo")
|
|
51
52
|
expect(call.default).to eq "foo"
|
|
52
53
|
end
|
|
53
54
|
|
|
54
55
|
it "should not extract symbol defaults" do
|
|
55
|
-
call = call(no_scope, :key, :
|
|
56
|
+
call = call(no_scope, :key, default: :bar_key)
|
|
56
57
|
expect(call.default).to be_nil
|
|
57
58
|
end
|
|
58
59
|
|
|
59
60
|
it "should extract the first string default" do
|
|
60
|
-
call = call(no_scope, :key, :
|
|
61
|
+
call = call(no_scope, :key, default: [:foo_key, :bar_key, "baz"])
|
|
61
62
|
expect(call.default).to eq "baz"
|
|
62
63
|
end
|
|
63
64
|
|
|
64
65
|
it "should ensure options is a hash, if provided" do
|
|
65
|
-
expect
|
|
66
|
+
expect do
|
|
66
67
|
call(no_scope, :key, "value", Object.new)
|
|
67
|
-
|
|
68
|
+
end.to raise_error(I18nliner::InvalidSignatureError)
|
|
68
69
|
end
|
|
69
70
|
end
|
|
70
71
|
|
|
@@ -72,28 +73,30 @@ describe I18nliner::Extractors::TranslateCall do
|
|
|
72
73
|
it "should generate literal keys" do
|
|
73
74
|
I18nliner.inferred_key_format :literal do
|
|
74
75
|
expect(call(no_scope, "zomg key").translations).to eq(
|
|
75
|
-
[["zomg key", "zomg key"]]
|
|
76
|
+
[["zomg key", "zomg key"]]
|
|
77
|
+
)
|
|
76
78
|
end
|
|
77
79
|
end
|
|
78
80
|
|
|
79
81
|
it "should generate underscored keys" do
|
|
80
82
|
I18nliner.inferred_key_format :underscored do
|
|
81
83
|
expect(call(no_scope, "zOmg key!!").translations).to eq(
|
|
82
|
-
[["zomg_key", "zOmg key!!"]]
|
|
84
|
+
[["zomg_key", "zOmg key!!"]]
|
|
85
|
+
)
|
|
83
86
|
end
|
|
84
87
|
end
|
|
85
88
|
|
|
86
89
|
it "should transliterate underscored keys according to the default locale" do
|
|
87
90
|
orig_locale = I18n.default_locale
|
|
88
|
-
I18n.available_locales = [
|
|
89
|
-
I18n.backend.store_translations(:de, :
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
91
|
+
I18n.available_locales = %i[en de]
|
|
92
|
+
I18n.backend.store_translations(:de, i18n: {
|
|
93
|
+
transliterate: {
|
|
94
|
+
rule: {
|
|
95
|
+
"ü" => "ue",
|
|
96
|
+
"ö" => "oe"
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
})
|
|
97
100
|
|
|
98
101
|
I18nliner.inferred_key_format :underscored do
|
|
99
102
|
I18n.default_locale = :en
|
|
@@ -107,15 +110,16 @@ describe I18nliner::Extractors::TranslateCall do
|
|
|
107
110
|
it "should generate underscored + crc32 keys" do
|
|
108
111
|
I18nliner.inferred_key_format :underscored_crc32 do
|
|
109
112
|
expect(call(no_scope, "zOmg key!!").translations).to eq(
|
|
110
|
-
[["zomg_key_90a85b0b", "zOmg key!!"]]
|
|
113
|
+
[["zomg_key_90a85b0b", "zOmg key!!"]]
|
|
114
|
+
)
|
|
111
115
|
end
|
|
112
116
|
end
|
|
113
117
|
end
|
|
114
118
|
|
|
115
119
|
describe "normalization" do
|
|
116
120
|
it "should make keys absolute if scoped" do
|
|
117
|
-
expect(call(scope,
|
|
118
|
-
expect(call(scope, [
|
|
121
|
+
expect(call(scope, ".key", "value").translations[0][0]).to match(/\Afoo\.key/)
|
|
122
|
+
expect(call(scope, [".key1", ".key2"], "value").translations.map(&:first)).to eq ["foo.key1", "foo.key2"]
|
|
119
123
|
end
|
|
120
124
|
|
|
121
125
|
it "should strip leading whitespace from defaults" do
|
|
@@ -130,81 +134,85 @@ describe I18nliner::Extractors::TranslateCall do
|
|
|
130
134
|
describe "pluralization" do
|
|
131
135
|
describe "keys" do
|
|
132
136
|
it "should be inferred from a word" do
|
|
133
|
-
translations = call(no_scope, "person", {:
|
|
137
|
+
translations = call(no_scope, "person", { count: Object.new }).translations
|
|
134
138
|
expect(translations.map(&:first).sort).to eq ["count_people_489946e7.one", "count_people_489946e7.other"]
|
|
135
139
|
end
|
|
136
140
|
|
|
137
141
|
it "should be inferred from a hash" do
|
|
138
|
-
translations = call(no_scope,
|
|
142
|
+
translations = call(no_scope,
|
|
143
|
+
{ one: "just you", other: "lotsa peeps" },
|
|
144
|
+
{ count: Object.new }).translations
|
|
139
145
|
expect(translations.map(&:first).sort).to eq ["lotsa_peeps_41499c40.one", "lotsa_peeps_41499c40.other"]
|
|
140
146
|
end
|
|
141
147
|
end
|
|
142
148
|
|
|
143
149
|
describe "defaults" do
|
|
144
150
|
it "should be inferred" do
|
|
145
|
-
translations = call(no_scope, "person", {:
|
|
151
|
+
translations = call(no_scope, "person", { count: Object.new }).translations
|
|
146
152
|
expect(translations.map(&:last).sort).to eq ["%{count} people", "1 person"]
|
|
147
153
|
end
|
|
148
154
|
|
|
149
155
|
it "should not be inferred if given multiple words" do
|
|
150
|
-
translations = call(no_scope, "happy person", {:
|
|
156
|
+
translations = call(no_scope, "happy person", { count: Object.new }).translations
|
|
151
157
|
expect(translations.map(&:last)).to eq ["happy person"]
|
|
152
158
|
end
|
|
153
159
|
end
|
|
154
160
|
|
|
155
161
|
it "should accept valid hashes" do
|
|
156
|
-
expect(call(no_scope, {:
|
|
157
|
-
[["qwerty_98185351.one", "asdf"], ["qwerty_98185351.other", "qwerty"]]
|
|
158
|
-
|
|
159
|
-
|
|
162
|
+
expect(call(no_scope, { one: "asdf", other: "qwerty" }, count: 1).translations.sort).to eq(
|
|
163
|
+
[["qwerty_98185351.one", "asdf"], ["qwerty_98185351.other", "qwerty"]]
|
|
164
|
+
)
|
|
165
|
+
expect(call(no_scope, :some_stuff, { one: "asdf", other: "qwerty" }, count: 1).translations.sort).to eq(
|
|
166
|
+
[["some_stuff.one", "asdf"], ["some_stuff.other", "qwerty"]]
|
|
167
|
+
)
|
|
160
168
|
end
|
|
161
169
|
|
|
162
170
|
it "should reject invalid keys" do
|
|
163
|
-
expect
|
|
164
|
-
call(no_scope, {:
|
|
165
|
-
|
|
171
|
+
expect do
|
|
172
|
+
call(no_scope, { one: "asdf", twenty: "qwerty" }, count: 1)
|
|
173
|
+
end.to raise_error(I18nliner::InvalidPluralizationKeyError)
|
|
166
174
|
end
|
|
167
175
|
|
|
168
176
|
it "should require essential keys" do
|
|
169
|
-
expect
|
|
170
|
-
call(no_scope, {:
|
|
171
|
-
|
|
177
|
+
expect do
|
|
178
|
+
call(no_scope, { one: "asdf" }, count: 1)
|
|
179
|
+
end.to raise_error(I18nliner::MissingPluralizationKeyError)
|
|
172
180
|
end
|
|
173
181
|
|
|
174
182
|
it "should reject invalid count defaults" do
|
|
175
|
-
expect
|
|
176
|
-
call(no_scope, {:
|
|
177
|
-
|
|
183
|
+
expect do
|
|
184
|
+
call(no_scope, { one: "asdf", other: Object.new }, count: 1)
|
|
185
|
+
end.to raise_error(I18nliner::InvalidPluralizationDefaultError)
|
|
178
186
|
end
|
|
179
187
|
|
|
180
188
|
it "should complain if no :count is provided" do
|
|
181
|
-
expect
|
|
182
|
-
call(no_scope, {:
|
|
183
|
-
|
|
189
|
+
expect do
|
|
190
|
+
call(no_scope, { one: "asdf", other: "qwerty" })
|
|
191
|
+
end.to raise_error(I18nliner::MissingCountValueError)
|
|
184
192
|
end
|
|
185
193
|
end
|
|
186
194
|
|
|
187
195
|
describe "validation" do
|
|
188
196
|
it "should require all interpolation values" do
|
|
189
197
|
I18nliner.infer_interpolation_values false do
|
|
190
|
-
expect
|
|
198
|
+
expect do
|
|
191
199
|
call(no_scope, "asdf %{bob}")
|
|
192
|
-
|
|
200
|
+
end.to raise_error(I18nliner::MissingInterpolationValueError)
|
|
193
201
|
end
|
|
194
202
|
end
|
|
195
203
|
|
|
196
204
|
it "should require all interpolation values in count defaults" do
|
|
197
205
|
I18nliner.infer_interpolation_values false do
|
|
198
|
-
expect
|
|
199
|
-
call(no_scope, {:
|
|
200
|
-
|
|
206
|
+
expect do
|
|
207
|
+
call(no_scope, { one: "asdf %{bob}", other: "querty" })
|
|
208
|
+
end.to raise_error(I18nliner::MissingInterpolationValueError)
|
|
201
209
|
end
|
|
202
210
|
end
|
|
203
211
|
|
|
204
212
|
it "should ensure option keys are symbols or strings" do
|
|
205
|
-
expect
|
|
206
|
-
call(no_scope, "hello", {Object.new => "okay"})
|
|
207
|
-
|
|
213
|
+
expect do
|
|
214
|
+
call(no_scope, "hello", { Object.new => "okay" })
|
|
215
|
+
end.to raise_error(I18nliner::InvalidOptionKeyError)
|
|
208
216
|
end
|
|
209
217
|
end
|
|
210
218
|
end
|
|
@@ -1,38 +1,39 @@
|
|
|
1
|
-
|
|
2
|
-
require 'i18nliner/extractors/translation_hash'
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
require "i18nliner/errors"
|
|
4
|
+
require "i18nliner/extractors/translation_hash"
|
|
5
5
|
|
|
6
|
+
describe I18nliner::Extractors::TranslationHash do
|
|
6
7
|
describe "#[]=" do
|
|
7
8
|
let(:hash) { I18nliner::Extractors::TranslationHash.new }
|
|
8
9
|
|
|
9
10
|
it "should accept identical key/values" do
|
|
10
|
-
expect
|
|
11
|
+
expect do
|
|
11
12
|
hash["foo"] = "Foo"
|
|
12
13
|
hash["foo"] = "Foo"
|
|
13
|
-
|
|
14
|
-
expect(hash).to eq({"foo" => "Foo"})
|
|
14
|
+
end.not_to raise_error
|
|
15
|
+
expect(hash).to eq({ "foo" => "Foo" })
|
|
15
16
|
end
|
|
16
17
|
|
|
17
18
|
it "should reject mismatched values" do
|
|
18
|
-
expect
|
|
19
|
+
expect do
|
|
19
20
|
hash["foo"] = "Foo"
|
|
20
21
|
hash["foo"] = "Bar"
|
|
21
|
-
|
|
22
|
+
end.to raise_error(I18nliner::KeyInUseError)
|
|
22
23
|
end
|
|
23
24
|
|
|
24
25
|
it "should not let you use a key as a scope" do
|
|
25
|
-
expect
|
|
26
|
+
expect do
|
|
26
27
|
hash["foo"] = "Foo"
|
|
27
28
|
hash["foo.bar"] = "Bar"
|
|
28
|
-
|
|
29
|
+
end.to raise_error(I18nliner::KeyAsScopeError)
|
|
29
30
|
end
|
|
30
31
|
|
|
31
32
|
it "should not let you use a scope as a key" do
|
|
32
|
-
expect
|
|
33
|
+
expect do
|
|
33
34
|
hash["foo.bar"] = "Bar"
|
|
34
35
|
hash["foo"] = "Foo"
|
|
35
|
-
|
|
36
|
+
end.to raise_error(I18nliner::KeyAsScopeError)
|
|
36
37
|
end
|
|
37
38
|
end
|
|
38
39
|
end
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/pre_processors/erb_pre_processor"
|
|
4
|
+
require "i18nliner/errors"
|
|
5
|
+
require "active_support/core_ext/string/strip"
|
|
5
6
|
|
|
6
7
|
describe I18nliner::PreProcessors::ErbPreProcessor do
|
|
7
8
|
before do
|
|
8
|
-
allow_any_instance_of(I18nliner::PreProcessors::ErbPreProcessor::TBlock).to receive(:infer_key).and_return(:key)
|
|
9
|
+
allow_any_instance_of(I18nliner::PreProcessors::ErbPreProcessor::TBlock).to receive(:infer_key).and_return(:key) # rubocop:disable RSpec/AnyInstance
|
|
9
10
|
end
|
|
10
11
|
|
|
11
12
|
describe ".process" do
|
|
12
|
-
def process(string, remove_blank_lines
|
|
13
|
+
def process(string, remove_blank_lines: true)
|
|
13
14
|
result = I18nliner::PreProcessors::ErbPreProcessor.process(string)
|
|
14
15
|
result.gsub!(/\n+%>/, " %>") if remove_blank_lines
|
|
15
16
|
result
|
|
@@ -17,12 +18,14 @@ describe I18nliner::PreProcessors::ErbPreProcessor do
|
|
|
17
18
|
|
|
18
19
|
it "should transform t block expressions" do
|
|
19
20
|
expect(process("<%= t do %>hello world!<% end %>")).to eq(
|
|
20
|
-
'<%= t :key, "hello world!", :i18nliner_inferred_key => (true) %>'
|
|
21
|
+
'<%= t :key, "hello world!", :i18nliner_inferred_key => (true) %>'
|
|
22
|
+
)
|
|
21
23
|
end
|
|
22
24
|
|
|
23
25
|
it "should remove extraneous whitespace from the default" do
|
|
24
26
|
expect(process("<%= t do %> ohai! lulz\t <% end %>")).to eq(
|
|
25
|
-
'<%= t :key, "ohai! lulz", :i18nliner_inferred_key => (true) %>'
|
|
27
|
+
'<%= t :key, "ohai! lulz", :i18nliner_inferred_key => (true) %>'
|
|
28
|
+
)
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
# so that line numbers are close-ish when you get an error in a
|
|
@@ -30,165 +33,165 @@ describe I18nliner::PreProcessors::ErbPreProcessor do
|
|
|
30
33
|
# match up perfectly, but it will at least point to the start of the
|
|
31
34
|
# t-block
|
|
32
35
|
it "should preserve all newlines in the generated erb" do
|
|
33
|
-
expect(process(
|
|
36
|
+
expect(process(<<~ERB.strip_heredoc, remove_blank_lines: false)).
|
|
34
37
|
<%= t do
|
|
35
38
|
%>
|
|
36
39
|
ohai!
|
|
37
40
|
<%= test %>
|
|
38
41
|
lulz
|
|
39
42
|
<% end %>
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
+
ERB
|
|
44
|
+
to eq <<~ERB.strip_heredoc
|
|
45
|
+
<%= t :key, "ohai! %{test} lulz", :test => (test), :i18nliner_inferred_key => (true)
|
|
43
46
|
|
|
44
47
|
|
|
45
48
|
|
|
46
49
|
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
%>
|
|
51
|
+
ERB
|
|
49
52
|
end
|
|
50
53
|
|
|
51
54
|
it "should not translate other block expressions" do
|
|
52
|
-
expect(process(
|
|
55
|
+
expect(process(<<~ERB)).
|
|
53
56
|
<%= form_for do %>
|
|
54
57
|
<%= t do %>Your Name<% end %>
|
|
55
58
|
<input>
|
|
56
59
|
<% end %>
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
ERB
|
|
61
|
+
to eq <<~ERB
|
|
62
|
+
<%= form_for do %>
|
|
63
|
+
<%= t :key, "Your Name", :i18nliner_inferred_key => (true) %>
|
|
64
|
+
<input>
|
|
65
|
+
<% end %>
|
|
66
|
+
ERB
|
|
64
67
|
end
|
|
65
68
|
|
|
66
69
|
it "should reject malformed erb" do
|
|
67
|
-
expect { process("<%= t do %>") }
|
|
68
|
-
to raise_error(I18nliner::MalformedErbError)
|
|
70
|
+
expect { process("<%= t do %>") }
|
|
71
|
+
.to raise_error(I18nliner::MalformedErbError)
|
|
69
72
|
end
|
|
70
73
|
|
|
71
74
|
it "should disallow nesting non-t block expressions in a t block expression" do
|
|
72
|
-
expect { process("<%= t { %><%= s { %>nope<% } %><% } %>") }
|
|
73
|
-
to raise_error(I18nliner::TBlockNestingError)
|
|
74
|
-
expect { process("<%= t { %><%= s(:some, :args) { |args, here, too| %>nope<% } %><% } %>") }
|
|
75
|
-
to raise_error(I18nliner::TBlockNestingError)
|
|
75
|
+
expect { process("<%= t { %><%= s { %>nope<% } %><% } %>") }
|
|
76
|
+
.to raise_error(I18nliner::TBlockNestingError)
|
|
77
|
+
expect { process("<%= t { %><%= s(:some, :args) { |args, here, too| %>nope<% } %><% } %>") }
|
|
78
|
+
.to raise_error(I18nliner::TBlockNestingError)
|
|
76
79
|
end
|
|
77
80
|
|
|
78
81
|
it "should disallow statements in a t block expression" do
|
|
79
|
-
expect { process("<%= t { %>I am <% if happy %>happy<% else %>sad<% end %><% } %>") }
|
|
80
|
-
to raise_error(I18nliner::TBlockNestingError)
|
|
82
|
+
expect { process("<%= t { %>I am <% if happy %>happy<% else %>sad<% end %><% } %>") }
|
|
83
|
+
.to raise_error(I18nliner::TBlockNestingError)
|
|
81
84
|
end
|
|
82
85
|
|
|
83
86
|
it "should create wrappers for markup" do
|
|
84
|
-
expect(process(
|
|
87
|
+
expect(process(<<~ERB)).
|
|
85
88
|
<%= t do %>
|
|
86
89
|
<b>bold</b>, or even <a href="#"><i><img>combos</i></a> get wrapper'd
|
|
87
90
|
<% end %>
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
91
|
+
ERB
|
|
92
|
+
to eq <<~ERB
|
|
93
|
+
<%= t :key, "*bold*, or even **combos** get wrapper'd", :i18nliner_inferred_key => (true), :wrappers => ["<b>\\\\1</b>", "<a href=\\"#\\"><i><img>\\\\1</i></a>"] %>
|
|
94
|
+
ERB
|
|
92
95
|
end
|
|
93
96
|
|
|
94
97
|
it "should not create wrappers for markup with multiple text nodes" do
|
|
95
|
-
expect {
|
|
96
|
-
to raise_error(I18nliner::UnwrappableContentError)
|
|
98
|
+
expect { process("<%= t do %>this is <b><i>too</i> complicated</b><% end %>") }
|
|
99
|
+
.to raise_error(I18nliner::UnwrappableContentError)
|
|
97
100
|
end
|
|
98
101
|
|
|
99
102
|
it "should create wrappers for link_to calls with string content" do
|
|
100
|
-
expect(process(
|
|
103
|
+
expect(process(<<~ERB)).
|
|
101
104
|
<%= t do %>
|
|
102
105
|
You should <%= link_to("create a profile", "/profile") %>.
|
|
103
106
|
idk why <%= link_to "this " + "link", "/zomg" %> has concatention
|
|
104
107
|
<% end %>
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
108
|
+
ERB
|
|
109
|
+
to eq <<~ERB
|
|
110
|
+
<%= t :key, "You should *create a profile*. idk why **this link** has concatention", :i18nliner_inferred_key => (true), :wrappers => [link_to("\\\\1", "/profile"), link_to("\\\\1", "/zomg")] %>
|
|
111
|
+
ERB
|
|
109
112
|
end
|
|
110
113
|
|
|
111
114
|
it "should create wrappers for link_to calls with other content" do
|
|
112
|
-
expect(process(
|
|
115
|
+
expect(process(<<~ERB)).
|
|
113
116
|
<%= t do %>
|
|
114
117
|
Your account rep is <%= link_to(@user.name, "/user/\#{@user.id}") %>
|
|
115
118
|
<% end %>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
ERB
|
|
120
|
+
to eq <<~ERB
|
|
121
|
+
<%= t :key, "Your account rep is *%{user_name}*", :user_name => (@user.name), :i18nliner_inferred_key => (true), :wrappers => [link_to("\\\\1", "/user/\#{@user.id}")] %>
|
|
122
|
+
ERB
|
|
120
123
|
end
|
|
121
124
|
|
|
122
125
|
it "should reuse identical wrappers" do
|
|
123
|
-
expect(process(
|
|
126
|
+
expect(process(<<~ERB)).
|
|
124
127
|
<%= t do %>
|
|
125
128
|
the wrappers for
|
|
126
129
|
<%= link_to "these", url %> <%= link_to "links", url %> are the same,
|
|
127
130
|
as are the ones for
|
|
128
131
|
<b>these</b> <b>tags</b>
|
|
129
132
|
<% end %>
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
133
|
+
ERB
|
|
134
|
+
to eq <<~ERB
|
|
135
|
+
<%= t :key, "the wrappers for **these** **links** are the same, as are the ones for *these* *tags*", :i18nliner_inferred_key => (true), :wrappers => ["<b>\\\\1</b>", link_to("\\\\1", url)] %>
|
|
136
|
+
ERB
|
|
134
137
|
end
|
|
135
138
|
|
|
136
139
|
it "should generate placeholders for inline expressions" do
|
|
137
|
-
expect(process(
|
|
140
|
+
expect(process(<<~ERB)).
|
|
138
141
|
<%= t do %>
|
|
139
142
|
Hello, <%= name %>
|
|
140
143
|
<% end %>
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
ERB
|
|
145
|
+
to eq <<~ERB
|
|
146
|
+
<%= t :key, "Hello, %{name}", :name => (name), :i18nliner_inferred_key => (true) %>
|
|
147
|
+
ERB
|
|
145
148
|
end
|
|
146
149
|
|
|
147
150
|
it "should generate placeholders for inline expressions in wrappers" do
|
|
148
|
-
expect(process(
|
|
151
|
+
expect(process(<<~ERB)).
|
|
149
152
|
<%= t do %>
|
|
150
153
|
Go to <a href="/asdf" title="<%= name %>">your account</a>
|
|
151
154
|
<% end %>
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
155
|
+
ERB
|
|
156
|
+
to eq <<~ERB
|
|
157
|
+
<%= t :key, "Go to *your account*", :i18nliner_inferred_key => (true), :wrappers => ["<a href=\\"/asdf\\" title=\\"\#{name}\\">\\\\1</a>"] %>
|
|
158
|
+
ERB
|
|
156
159
|
end
|
|
157
160
|
|
|
158
161
|
# this is really the same as the one above, but it's good to have a
|
|
159
162
|
# spec for this in case the underlying implementation changes
|
|
160
163
|
# dramatically
|
|
161
164
|
it "should transform nested t block expressions in wrappers" do
|
|
162
|
-
expect(process(
|
|
165
|
+
expect(process(<<~ERB)).
|
|
163
166
|
<%= t do %>
|
|
164
167
|
Go to <a href="/asdf" title="<%= t do %>manage account stuffs, <%= name %><% end %>">your account</a>
|
|
165
168
|
<% end %>
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
169
|
+
ERB
|
|
170
|
+
to eq <<~ERB
|
|
171
|
+
<%= t :key, "Go to *your account*", :i18nliner_inferred_key => (true), :wrappers => ["<a href=\\"/asdf\\" title=\\"\#{t :key, "manage account stuffs, %{name}", :name => (name), :i18nliner_inferred_key => (true)}\\">\\\\1</a>"] %>
|
|
172
|
+
ERB
|
|
170
173
|
end
|
|
171
174
|
|
|
172
175
|
it "should generate placeholders for empty markup" do
|
|
173
|
-
expect(process(
|
|
176
|
+
expect(process(<<~ERB)).
|
|
174
177
|
<%= t do %>
|
|
175
178
|
Create <input name="count"> groups
|
|
176
179
|
<% end %>
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
180
|
+
ERB
|
|
181
|
+
to eq <<~ERB
|
|
182
|
+
<%= t :key, "Create %{input_name_count} groups", :input_name_count => ("<input name=\\"count\\">".html_safe), :i18nliner_inferred_key => (true) %>
|
|
183
|
+
ERB
|
|
181
184
|
end
|
|
182
185
|
|
|
183
186
|
it "should unescape entities" do
|
|
184
|
-
expect(process(
|
|
187
|
+
expect(process(<<~ERB)).
|
|
185
188
|
<%= t do %>
|
|
186
189
|
© <%= year %> ACME Corp. All Rights Reserved. Our lawyers > your lawyers
|
|
187
190
|
<% end %>
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
191
|
+
ERB
|
|
192
|
+
to eq <<~ERB
|
|
193
|
+
<%= t :key, "© %{year} ACME Corp. All Rights Reserved. Our lawyers > your lawyers", :year => (year), :i18nliner_inferred_key => (true) %>
|
|
194
|
+
ERB
|
|
192
195
|
end
|
|
193
196
|
end
|
|
194
197
|
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/processors/erb_processor"
|
|
4
|
+
require "i18nliner/extractors/translation_hash"
|
|
5
|
+
require "i18nliner/scope"
|
|
6
|
+
|
|
7
|
+
describe I18nliner::Processors::ErbProcessor do
|
|
8
|
+
let(:translations) { I18nliner::Extractors::TranslationHash.new }
|
|
9
|
+
let(:processor) { I18nliner::Processors::ErbProcessor.new(translations) }
|
|
10
|
+
|
|
11
|
+
describe "#scope_for" do
|
|
12
|
+
context "with an erb template" do
|
|
13
|
+
subject(:scope) { processor.scope_for("app/views/foos/show.html.erb") }
|
|
14
|
+
|
|
15
|
+
specify { expect(scope).to be_allow_relative }
|
|
16
|
+
specify { expect(scope).to be_remove_whitespace }
|
|
17
|
+
specify { expect(scope.scope).to eq "foos.show." }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
context "with anything else" do
|
|
21
|
+
subject(:scope) { processor.scope_for("foo.erb") }
|
|
22
|
+
|
|
23
|
+
specify { expect(scope).to be I18nliner::Scope.root }
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
describe "#check_contents" do
|
|
28
|
+
it "should extract valid translation calls" do
|
|
29
|
+
processor.check_contents(<<~ERB)
|
|
30
|
+
<%= t "Inline!" %>
|
|
31
|
+
<%= t do %>
|
|
32
|
+
Zomg a block
|
|
33
|
+
<a href="/nesting"
|
|
34
|
+
title="<%= t do %>what is this?<% end %>"
|
|
35
|
+
>with nesting</a>!!!
|
|
36
|
+
<% end %>
|
|
37
|
+
ERB
|
|
38
|
+
expect(translations.values.sort).to eq [
|
|
39
|
+
"Inline!",
|
|
40
|
+
"Zomg a block *with nesting*!!!",
|
|
41
|
+
"what is this?"
|
|
42
|
+
]
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|