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
data/lib/i18nliner/railtie.rb
CHANGED
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/extensions/controller"
|
|
4
|
+
require "i18nliner/extensions/view"
|
|
5
|
+
require "i18nliner/extensions/model"
|
|
4
6
|
|
|
5
7
|
module I18nliner
|
|
6
8
|
class Railtie < Rails::Railtie
|
|
7
|
-
initializer
|
|
9
|
+
initializer "i18nliner" do
|
|
8
10
|
ActiveSupport.on_load :action_controller do
|
|
9
|
-
ActionController::Base.
|
|
11
|
+
ActionController::Base.include I18nliner::Extensions::Controller
|
|
10
12
|
end
|
|
11
13
|
|
|
12
14
|
ActiveSupport.on_load :action_view do
|
|
13
|
-
require
|
|
15
|
+
require "i18nliner/erubi"
|
|
14
16
|
ActionView::Template::Handlers::ERB.erb_implementation = I18nliner::Erubi
|
|
15
|
-
ActionView::Base.
|
|
17
|
+
ActionView::Base.include I18nliner::Extensions::View
|
|
16
18
|
end
|
|
17
19
|
|
|
18
20
|
ActiveSupport.on_load :active_record do
|
|
19
|
-
ActiveRecord::Base.
|
|
21
|
+
ActiveRecord::Base.include I18nliner::Extensions::Model
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
|
|
@@ -25,5 +27,3 @@ module I18nliner
|
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
end
|
|
28
|
-
|
|
29
|
-
|
data/lib/i18nliner/scope.rb
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module I18nliner
|
|
2
4
|
class Scope
|
|
3
|
-
attr_reader :scope
|
|
4
|
-
|
|
5
|
-
attr_reader :context
|
|
6
|
-
alias :allow_relative? :allow_relative
|
|
5
|
+
attr_reader :scope, :allow_relative, :context
|
|
6
|
+
alias_method :allow_relative?, :allow_relative
|
|
7
7
|
attr_accessor :remove_whitespace
|
|
8
|
-
|
|
8
|
+
alias_method :remove_whitespace?, :remove_whitespace
|
|
9
9
|
|
|
10
10
|
def initialize(scope = nil, options = {})
|
|
11
11
|
@scope = scope ? "#{scope}." : scope
|
|
@@ -16,12 +16,10 @@ module I18nliner
|
|
|
16
16
|
|
|
17
17
|
def normalize_key(key, inferred, i18n_scope)
|
|
18
18
|
return key if key.nil?
|
|
19
|
-
if key.is_a?(Array)
|
|
20
|
-
return key.map { |k| normalize_key(k, inferred, i18n_scope) }
|
|
21
|
-
end
|
|
19
|
+
return key.map { |k| normalize_key(k, inferred, i18n_scope) } if key.is_a?(Array)
|
|
22
20
|
|
|
23
21
|
key = key.to_s.dup
|
|
24
|
-
if allow_relative? && key.
|
|
22
|
+
if allow_relative? && key.delete_prefix!(".")
|
|
25
23
|
scope + key
|
|
26
24
|
else
|
|
27
25
|
key
|
data/lib/i18nliner.rb
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
require 'i18nliner/base'
|
|
1
|
+
# frozen_string_literal: true
|
|
3
2
|
|
|
4
|
-
require
|
|
5
|
-
|
|
6
|
-
require 'i18nliner/reserved_keys'
|
|
3
|
+
require "i18n"
|
|
4
|
+
require "i18nliner/base"
|
|
7
5
|
|
|
8
|
-
require
|
|
6
|
+
require "i18nliner/extensions/core"
|
|
7
|
+
I18n.extend I18nliner::Extensions::Core
|
|
8
|
+
require "i18nliner/reserved_keys"
|
|
9
|
+
|
|
10
|
+
require "i18nliner/railtie" if defined?(Rails)
|
data/lib/tasks/i18nliner.rake
CHANGED
|
@@ -1,20 +1,21 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
namespace :i18nliner do
|
|
2
4
|
desc "Verifies all translation calls"
|
|
3
|
-
task :
|
|
4
|
-
require
|
|
5
|
+
task check: :environment do
|
|
6
|
+
require "i18nliner/commands/check"
|
|
5
7
|
|
|
6
|
-
options = {:
|
|
8
|
+
options = { only: ENV["ONLY"] }
|
|
7
9
|
@command = I18nliner::Commands::Check.run(options)
|
|
8
10
|
@command.success? or exit 1
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
desc "Generates a new [default_locale].yml file for all translations"
|
|
12
|
-
task :
|
|
13
|
-
require
|
|
14
|
+
task dump: :check do
|
|
15
|
+
require "i18nliner/commands/dump"
|
|
14
16
|
|
|
15
|
-
options = {:
|
|
17
|
+
options = { translations: @command.translations, file: ENV["YML_FILE"] }
|
|
16
18
|
@command = I18nliner::Commands::Dump.run(options)
|
|
17
19
|
@command.success? or exit 1
|
|
18
20
|
end
|
|
19
21
|
end
|
|
20
|
-
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/commands/check"
|
|
2
4
|
|
|
3
5
|
describe I18nliner::Commands::Check do
|
|
4
6
|
describe ".run" do
|
|
5
|
-
|
|
6
7
|
around do |example|
|
|
7
8
|
I18nliner.base_path "spec/fixtures" do
|
|
8
9
|
example.run
|
|
@@ -11,13 +12,11 @@ describe I18nliner::Commands::Check do
|
|
|
11
12
|
|
|
12
13
|
it "should find errors" do
|
|
13
14
|
allow(I18nliner).to receive(:manual_translations).and_return({})
|
|
14
|
-
checker = I18nliner::Commands::Check.new({:
|
|
15
|
+
checker = I18nliner::Commands::Check.new({ silent: true })
|
|
15
16
|
checker.check_files
|
|
16
17
|
expect(checker.translations.values).to eq ["welcome, %{name}", "Hello World", "*This* is a test, %{user}"]
|
|
17
18
|
expect(checker.errors.size).to eq 2
|
|
18
|
-
checker.errors.
|
|
19
|
-
expect(error).to match /\Ainvalid signature/
|
|
20
|
-
end
|
|
19
|
+
expect(checker.errors).to all(match(/\Ainvalid signature/))
|
|
21
20
|
end
|
|
22
21
|
end
|
|
23
22
|
end
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/commands/dump"
|
|
4
|
+
require "i18nliner/extractors/translation_hash"
|
|
5
|
+
require "tmpdir"
|
|
5
6
|
|
|
6
7
|
describe I18nliner::Commands::Dump do
|
|
7
8
|
describe ".run" do
|
|
8
|
-
|
|
9
9
|
around do |example|
|
|
10
10
|
Dir.mktmpdir do |dir|
|
|
11
11
|
I18nliner.base_path dir do
|
|
@@ -15,15 +15,14 @@ describe I18nliner::Commands::Dump do
|
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
it "should dump translations in utf8" do
|
|
18
|
-
translations = I18nliner::Extractors::TranslationHash.new(
|
|
19
|
-
dumper = I18nliner::Commands::Dump.new({:
|
|
18
|
+
translations = I18nliner::Extractors::TranslationHash.new("i18n" => "Iñtërnâtiônàlizætiøn")
|
|
19
|
+
dumper = I18nliner::Commands::Dump.new({ silent: true, translations: })
|
|
20
20
|
dumper.run
|
|
21
|
-
expect(File.read(dumper.yml_file).gsub(/\s+$/,
|
|
21
|
+
expect(File.read(dumper.yml_file).gsub(/\s+$/, "")).to eq <<~YAML.strip
|
|
22
22
|
---
|
|
23
23
|
#{I18n.default_locale}:
|
|
24
24
|
i18n: Iñtërnâtiônàlizætiøn
|
|
25
|
-
|
|
25
|
+
YAML
|
|
26
26
|
end
|
|
27
27
|
end
|
|
28
28
|
end
|
|
29
|
-
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/extensions/controller"
|
|
4
|
+
require "i18nliner/call_helpers"
|
|
4
5
|
|
|
5
6
|
describe I18nliner::Extensions::Controller do
|
|
6
7
|
let(:i18n) do
|
|
@@ -19,21 +20,21 @@ describe I18nliner::Extensions::Controller do
|
|
|
19
20
|
end
|
|
20
21
|
end
|
|
21
22
|
|
|
22
|
-
|
|
23
23
|
describe "#translate" do
|
|
24
24
|
it "should inferpolate" do
|
|
25
25
|
allow(i18n).to receive(:foo).and_return("FOO")
|
|
26
26
|
allow(I18nliner::CallHelpers).to receive(:infer_key).and_return(:key)
|
|
27
27
|
|
|
28
|
-
expect(I18n).to receive(:translate).with(:key,
|
|
28
|
+
expect(I18n).to receive(:translate).with(:key,
|
|
29
|
+
default: "hello %{foo}",
|
|
30
|
+
foo: "FOO",
|
|
31
|
+
i18nliner_scope: i18n.i18nliner_scope)
|
|
29
32
|
i18n.translate("hello %{foo}")
|
|
30
33
|
end
|
|
31
34
|
|
|
32
35
|
it "should pass along its scope to I18n.t" do
|
|
33
|
-
expect(I18n).to receive(:translate).with(:key, :
|
|
36
|
+
expect(I18n).to receive(:translate).with(:key, default: "foo", i18nliner_scope: i18n.i18nliner_scope)
|
|
34
37
|
i18n.translate(:key, "foo")
|
|
35
38
|
end
|
|
36
39
|
end
|
|
37
40
|
end
|
|
38
|
-
|
|
39
|
-
|
|
@@ -1,19 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18n"
|
|
4
|
+
require "i18nliner/extensions/core"
|
|
3
5
|
|
|
4
6
|
describe I18nliner::Extensions::Core do
|
|
5
7
|
let(:i18n) do
|
|
6
8
|
Module.new do
|
|
7
9
|
extend(Module.new do
|
|
8
10
|
def translate(key, **options)
|
|
9
|
-
if RUBY_VERSION >=
|
|
11
|
+
if RUBY_VERSION >= "3.0"
|
|
10
12
|
simple_translate(key, **options)
|
|
11
13
|
else
|
|
12
14
|
simple_translate(key, options)
|
|
13
15
|
end
|
|
14
16
|
end
|
|
15
17
|
|
|
16
|
-
def simple_translate(
|
|
18
|
+
def simple_translate(_key, **options)
|
|
17
19
|
string = options.delete(:default)
|
|
18
20
|
interpolate_hash(string, options)
|
|
19
21
|
end
|
|
@@ -28,66 +30,71 @@ describe I18nliner::Extensions::Core do
|
|
|
28
30
|
|
|
29
31
|
describe ".translate" do
|
|
30
32
|
it "should should normalize the arguments passed into the original translate" do
|
|
31
|
-
expect(i18n).to receive(:simple_translate).with("hello_name_84ff273f",
|
|
32
|
-
|
|
33
|
+
expect(i18n).to receive(:simple_translate).with("hello_name_84ff273f",
|
|
34
|
+
default: "Hello %{name}",
|
|
35
|
+
name: "bob")
|
|
36
|
+
i18n.translate("Hello %{name}", name: "bob")
|
|
33
37
|
end
|
|
34
38
|
|
|
35
39
|
it "should not mutate the arguments passed in" do
|
|
36
|
-
expect(i18n).to receive(:simple_translate).with("my.key", :
|
|
37
|
-
key = "my.key"
|
|
38
|
-
default = " ohai whitespace "
|
|
39
|
-
expect
|
|
40
|
+
expect(i18n).to receive(:simple_translate).with("my.key", default: "ohai whitespace ")
|
|
41
|
+
key = "my.key"
|
|
42
|
+
default = " ohai whitespace "
|
|
43
|
+
expect do
|
|
40
44
|
i18n.translate(key, default)
|
|
41
|
-
|
|
45
|
+
end.not_to raise_error
|
|
42
46
|
end
|
|
43
47
|
|
|
44
48
|
it "should infer pluralization hashes" do
|
|
45
|
-
expect(i18n).to receive(:simple_translate).with("count_lights_58339e29",
|
|
46
|
-
|
|
49
|
+
expect(i18n).to receive(:simple_translate).with("count_lights_58339e29",
|
|
50
|
+
default: { one: "1 light", other: "%{count} lights" },
|
|
51
|
+
count: 1)
|
|
52
|
+
i18n.translate("light", count: 1)
|
|
47
53
|
end
|
|
48
54
|
|
|
49
55
|
it "should not stringify nil keys" do
|
|
50
|
-
expect(i18n).to receive(:simple_translate).with(nil, {:
|
|
51
|
-
i18n.translate(nil, {:
|
|
56
|
+
expect(i18n).to receive(:simple_translate).with(nil, { default: %i[foo bar] })
|
|
57
|
+
i18n.translate(nil, { default: %i[foo bar] })
|
|
52
58
|
end
|
|
53
59
|
|
|
54
60
|
it "should stringify array keys, but not the array itself" do
|
|
55
|
-
if RUBY_VERSION >=
|
|
56
|
-
expect(i18n).to receive(:simple_translate).with([
|
|
61
|
+
if RUBY_VERSION >= "3.0"
|
|
62
|
+
expect(i18n).to receive(:simple_translate).with(%w[bar baz])
|
|
57
63
|
else
|
|
58
|
-
expect(i18n).to receive(:simple_translate).with([
|
|
64
|
+
expect(i18n).to receive(:simple_translate).with(%w[bar baz], {})
|
|
59
65
|
end
|
|
60
|
-
i18n.translate([
|
|
66
|
+
i18n.translate(%i[bar baz])
|
|
61
67
|
end
|
|
62
68
|
|
|
63
69
|
context "with wrappers" do
|
|
64
70
|
it "should apply a single wrapper" do
|
|
65
|
-
result = i18n.translate("Hello *bob*.", :
|
|
71
|
+
result = i18n.translate("Hello *bob*.", wrapper: '<b>\1</b>')
|
|
66
72
|
expect(result).to eq "Hello <b>bob</b>."
|
|
67
73
|
end
|
|
68
74
|
|
|
69
75
|
it "should be html-safe" do
|
|
70
|
-
result = i18n.translate("Hello *bob*.", :
|
|
76
|
+
result = i18n.translate("Hello *bob*.", wrapper: '<b>\1</b>')
|
|
71
77
|
expect(result).to be_html_safe
|
|
72
78
|
end
|
|
73
79
|
|
|
74
80
|
it "should apply multiple wrappers" do
|
|
75
|
-
result = i18n.translate("Hello *bob*. Click **here**", :
|
|
81
|
+
result = i18n.translate("Hello *bob*. Click **here**", wrappers: ['<b>\1</b>', '<a href="/">\1</a>'])
|
|
76
82
|
expect(result).to eq "Hello <b>bob</b>. Click <a href=\"/\">here</a>"
|
|
77
83
|
end
|
|
78
84
|
|
|
79
85
|
it "should apply multiple wrappers with arbitrary delimiters" do
|
|
80
|
-
result = i18n.translate("Hello !!!bob!!!. Click ???here???",
|
|
86
|
+
result = i18n.translate("Hello !!!bob!!!. Click ???here???",
|
|
87
|
+
wrappers: { "!!!" => '<b>\1</b>', "???" => '<a href="/">\1</a>' })
|
|
81
88
|
expect(result).to eq "Hello <b>bob</b>. Click <a href=\"/\">here</a>"
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
it "should html-escape the default when applying wrappers" do
|
|
85
|
-
expect(i18n.translate("*bacon* > narwhals", :
|
|
86
|
-
to eq "<b>bacon</b> > narwhals"
|
|
92
|
+
expect(i18n.translate("*bacon* > narwhals", wrappers: ['<b>\1</b>']))
|
|
93
|
+
.to eq "<b>bacon</b> > narwhals"
|
|
87
94
|
end
|
|
88
95
|
|
|
89
96
|
it "should allow escaping asterisks and backslashes" do
|
|
90
|
-
result = i18n.translate("Hello \\\\*b\\*b*.", :
|
|
97
|
+
result = i18n.translate("Hello \\\\*b\\*b*.", wrapper: '<b>\1</b>')
|
|
91
98
|
expect(result).to eq 'Hello \<b>b*b</b>.'
|
|
92
99
|
end
|
|
93
100
|
end
|
|
@@ -95,37 +102,41 @@ describe I18nliner::Extensions::Core do
|
|
|
95
102
|
|
|
96
103
|
describe ".translate!" do
|
|
97
104
|
it "should behave like translate" do
|
|
98
|
-
expect(i18n).to receive(:simple_translate).with("hello_name_84ff273f",
|
|
99
|
-
|
|
105
|
+
expect(i18n).to receive(:simple_translate).with("hello_name_84ff273f",
|
|
106
|
+
default: "Hello %{name}",
|
|
107
|
+
name: "bob")
|
|
108
|
+
i18n.translate!("Hello %{name}", name: "bob")
|
|
100
109
|
end
|
|
101
110
|
end
|
|
102
111
|
|
|
103
112
|
describe ".interpolate_hash" do
|
|
104
113
|
it "should not mark the result as html-safe if none of the components are html-safe" do
|
|
105
|
-
result = i18n.interpolate_hash("hello %{name}", :
|
|
114
|
+
result = i18n.interpolate_hash("hello %{name}", name: "<script>")
|
|
106
115
|
expect(result).to eq "hello <script>"
|
|
107
116
|
expect(result).not_to be_html_safe
|
|
108
117
|
end
|
|
109
118
|
|
|
110
119
|
it "should html-escape values if the string is html-safe" do
|
|
111
|
-
result = i18n.interpolate_hash("some markup: %{markup}".html_safe, :
|
|
120
|
+
result = i18n.interpolate_hash("some markup: %{markup}".html_safe, markup: "<html>")
|
|
112
121
|
expect(result).to eq "some markup: <html>"
|
|
113
122
|
expect(result).to be_html_safe
|
|
114
123
|
end
|
|
115
124
|
|
|
116
125
|
it "should html-escape the string and other values if any value is html-safe strings" do
|
|
117
126
|
markup = "<input>"
|
|
118
|
-
result = i18n.interpolate_hash("type %{input} & you get this: %{output}",
|
|
127
|
+
result = i18n.interpolate_hash("type %{input} & you get this: %{output}",
|
|
128
|
+
input: markup,
|
|
129
|
+
output: markup.html_safe)
|
|
119
130
|
expect(result).to eq "type <input> & you get this: <input>"
|
|
120
131
|
expect(result).to be_html_safe
|
|
121
132
|
end
|
|
122
133
|
|
|
123
134
|
it "should not html-escape the string if the html-safe values are not strings" do
|
|
124
|
-
|
|
125
|
-
|
|
135
|
+
result = i18n.interpolate_hash("my favorite number is %{number} & my favorite color is %{color}",
|
|
136
|
+
number: 1,
|
|
137
|
+
color: "red")
|
|
126
138
|
expect(result).to eq "my favorite number is 1 & my favorite color is red"
|
|
127
139
|
expect(result).not_to be_html_safe
|
|
128
140
|
end
|
|
129
141
|
end
|
|
130
142
|
end
|
|
131
|
-
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/extensions/inferpolation"
|
|
4
|
+
|
|
5
|
+
describe I18nliner::Extensions::Inferpolation do
|
|
6
|
+
let(:foo) do
|
|
7
|
+
bar = double(baz: "lol")
|
|
8
|
+
foo = double(bar:, bar2: "foo")
|
|
9
|
+
foo.instance_variable_set(:@bar, foo.bar)
|
|
10
|
+
foo.instance_variable_set(:@bar2, "foo")
|
|
11
|
+
foo.extend I18nliner::Extensions::Inferpolation
|
|
12
|
+
foo
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it "should inferpolate valid instance methods and chains" do
|
|
16
|
+
options = { default: "hello %{bar.baz} %{bar2}" }
|
|
17
|
+
expect(foo.inferpolate(options)).to eq({
|
|
18
|
+
default: "hello %{bar_baz} %{bar2}",
|
|
19
|
+
bar_baz: foo.bar.baz,
|
|
20
|
+
bar2: foo.bar2
|
|
21
|
+
})
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should inferpolate valid instance variables and chains" do
|
|
25
|
+
options = { default: "hello %{@bar.baz} %{@bar2}" }
|
|
26
|
+
expect(foo.inferpolate(options)).to eq({
|
|
27
|
+
default: "hello %{bar_baz} %{bar2}",
|
|
28
|
+
bar_baz: foo.bar.baz,
|
|
29
|
+
bar2: foo.bar2
|
|
30
|
+
})
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
it "should not inferpolate invalid instance methods and chains" do
|
|
34
|
+
options = { default: "hello %{lol} %{bar.baz.lol}" }
|
|
35
|
+
expect(foo.inferpolate(options)).to eq options
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
it "should not inferpolate invalid instance variables and chains" do
|
|
39
|
+
options = { default: "hello %{@lol} %{@bar.baz.lol}" }
|
|
40
|
+
expect(foo.inferpolate(options)).to eq options
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
it "should work with pluralization hashes" do
|
|
44
|
+
options = { default: { one: "%{bar2} has 1 item", other: "%{bar2} has %{count} items" } }
|
|
45
|
+
expect(foo.inferpolate(options)).to eq({
|
|
46
|
+
default: { one: "%{bar2} has 1 item",
|
|
47
|
+
other: "%{bar2} has %{count} items" },
|
|
48
|
+
bar2: foo.bar2
|
|
49
|
+
})
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/extensions/model"
|
|
4
|
+
require "i18nliner/call_helpers"
|
|
5
|
+
|
|
6
|
+
describe I18nliner::Extensions::Model do
|
|
7
|
+
let(:i18n) do
|
|
8
|
+
Module.new do
|
|
9
|
+
extend I18nliner::Extensions::Model
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
describe "#translate" do
|
|
14
|
+
it "should inferpolate" do
|
|
15
|
+
allow(i18n).to receive(:foo).and_return("FOO")
|
|
16
|
+
allow(I18nliner::CallHelpers).to receive(:infer_key).and_return(:key)
|
|
17
|
+
|
|
18
|
+
expect(I18n).to receive(:translate).with(:key,
|
|
19
|
+
default: "hello %{foo}",
|
|
20
|
+
foo: "FOO",
|
|
21
|
+
i18nliner_scope: i18n.i18nliner_scope,
|
|
22
|
+
i18nliner_inferred_key: true)
|
|
23
|
+
i18n.translate("hello %{foo}")
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it "should pass along its scope to I18n.t" do
|
|
27
|
+
expect(I18n).to receive(:translate).with(:key, default: "foo", i18nliner_scope: i18n.i18nliner_scope)
|
|
28
|
+
i18n.translate(:key, "foo")
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
#
|
|
2
|
-
|
|
3
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "i18nliner/extensions/view"
|
|
4
|
+
require "i18nliner/call_helpers"
|
|
4
5
|
|
|
5
6
|
describe I18nliner::Extensions::View do
|
|
6
7
|
let(:i18n) do
|
|
@@ -15,34 +16,35 @@ describe I18nliner::Extensions::View do
|
|
|
15
16
|
end
|
|
16
17
|
end
|
|
17
18
|
|
|
18
|
-
|
|
19
19
|
describe "#translate" do
|
|
20
20
|
it "should inferpolate" do
|
|
21
21
|
allow(i18n).to receive(:foo).and_return("FOO")
|
|
22
22
|
allow(I18nliner::CallHelpers).to receive(:infer_key).and_return(:key)
|
|
23
23
|
|
|
24
|
-
expect(I18n).to receive(:translate).with(:key,
|
|
24
|
+
expect(I18n).to receive(:translate).with(:key,
|
|
25
|
+
default: "hello %{foo}",
|
|
26
|
+
foo: "FOO",
|
|
27
|
+
i18nliner_scope: i18n.i18nliner_scope)
|
|
25
28
|
i18n.translate("hello %{foo}")
|
|
26
29
|
end
|
|
27
30
|
|
|
28
31
|
it "should raise an error when given a block" do
|
|
29
|
-
expect
|
|
30
|
-
i18n.translate(:foo)
|
|
32
|
+
expect do
|
|
33
|
+
i18n.translate(:foo) do
|
|
31
34
|
uhoh there was a bug with erb extraction or im doing it wrong
|
|
32
|
-
|
|
33
|
-
|
|
35
|
+
end
|
|
36
|
+
end.to raise_error I18nliner::InvalidBlockUsageError
|
|
34
37
|
end
|
|
35
38
|
|
|
36
39
|
it "should raise an error when given an incorrect number of arguments" do
|
|
37
|
-
expect
|
|
40
|
+
expect do
|
|
38
41
|
i18n.translate
|
|
39
|
-
|
|
42
|
+
end.to raise_error(/wrong number of arguments/)
|
|
40
43
|
end
|
|
41
44
|
|
|
42
45
|
it "should pass along its scope to I18n.t" do
|
|
43
|
-
expect(I18n).to receive(:translate).with(:key, :
|
|
46
|
+
expect(I18n).to receive(:translate).with(:key, default: "foo", i18nliner_scope: i18n.i18nliner_scope)
|
|
44
47
|
i18n.translate(:key, "foo")
|
|
45
48
|
end
|
|
46
49
|
end
|
|
47
50
|
end
|
|
48
|
-
|
|
@@ -1,22 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
require
|
|
4
|
-
require
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "prism"
|
|
4
|
+
require "i18nliner/errors"
|
|
5
|
+
require "i18nliner/scope"
|
|
6
|
+
require "i18nliner/extractors/ruby_extractor"
|
|
5
7
|
|
|
6
8
|
describe I18nliner::Extractors::RubyExtractor do
|
|
7
9
|
def extract(source, scope = I18nliner::Scope.new(nil))
|
|
8
|
-
sexps = RubyParser.new.parse(source)
|
|
10
|
+
sexps = Prism::Translation::RubyParser.new.parse(source)
|
|
9
11
|
extractor = I18nliner::Extractors::RubyExtractor.new(sexps, scope)
|
|
10
12
|
translations = []
|
|
11
13
|
extractor.each_translation { |translation| translations << translation }
|
|
12
|
-
|
|
14
|
+
translations.to_h
|
|
13
15
|
end
|
|
14
16
|
|
|
15
17
|
def assert_error(*args)
|
|
16
18
|
error = args.pop
|
|
17
|
-
expect
|
|
19
|
+
expect do
|
|
18
20
|
extract(*args)
|
|
19
|
-
|
|
21
|
+
end.to raise_error(error)
|
|
20
22
|
end
|
|
21
23
|
|
|
22
24
|
describe "#each_translation" do
|
|
@@ -34,19 +36,26 @@ describe I18nliner::Extractors::RubyExtractor do
|
|
|
34
36
|
|
|
35
37
|
it "should extract valid t calls" do
|
|
36
38
|
expect(extract("t 'Foo'")).to eq(
|
|
37
|
-
{"foo_f44ad75d" => "Foo"}
|
|
39
|
+
{ "foo_f44ad75d" => "Foo" }
|
|
40
|
+
)
|
|
38
41
|
expect(extract("t :bar, 'Baz'")).to eq(
|
|
39
|
-
{"bar" => "Baz"}
|
|
42
|
+
{ "bar" => "Baz" }
|
|
43
|
+
)
|
|
40
44
|
expect(extract("t 'lol', 'wut'")).to eq(
|
|
41
|
-
{"lol" => "wut"}
|
|
45
|
+
{ "lol" => "wut" }
|
|
46
|
+
)
|
|
42
47
|
expect(extract("translate 'one', {:one => '1', :other => '2'}, :count => 1")).to eq(
|
|
43
|
-
{"one.one" => "1", "one.other" => "2"}
|
|
48
|
+
{ "one.one" => "1", "one.other" => "2" }
|
|
49
|
+
)
|
|
44
50
|
expect(extract("t({:one => 'just one', :other => 'zomg lots'}, :count => 1)")).to eq(
|
|
45
|
-
{"zomg_lots_a54248c9.one" => "just one", "zomg_lots_a54248c9.other" => "zomg lots"}
|
|
51
|
+
{ "zomg_lots_a54248c9.one" => "just one", "zomg_lots_a54248c9.other" => "zomg lots" }
|
|
52
|
+
)
|
|
46
53
|
expect(extract("t 'foo2', <<-STR\nFoo\nSTR")).to eq(
|
|
47
|
-
{
|
|
54
|
+
{ "foo2" => "Foo" }
|
|
55
|
+
)
|
|
48
56
|
expect(extract("t 'foo', 'F' + 'o' + 'o'")).to eq(
|
|
49
|
-
{
|
|
57
|
+
{ "foo" => "Foo" }
|
|
58
|
+
)
|
|
50
59
|
end
|
|
51
60
|
|
|
52
61
|
it "should handle omitted values in hashes" do
|