i18n-tasks 0.8.7 → 0.9.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (86) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +6 -5
  3. data/CHANGES.md +3 -3
  4. data/Gemfile +1 -1
  5. data/README.md +4 -4
  6. data/bin/i18n-tasks +0 -1
  7. data/config/locales/en.yml +103 -102
  8. data/config/locales/ru.yml +1 -1
  9. data/i18n-tasks.gemspec +1 -2
  10. data/lib/i18n/tasks.rb +0 -1
  11. data/lib/i18n/tasks/base_task.rb +0 -1
  12. data/lib/i18n/tasks/cli.rb +1 -1
  13. data/lib/i18n/tasks/command/commander.rb +0 -1
  14. data/lib/i18n/tasks/command/commands/missing.rb +3 -15
  15. data/lib/i18n/tasks/command/commands/usages.rb +5 -6
  16. data/lib/i18n/tasks/command/option_parsers/locale.rb +1 -8
  17. data/lib/i18n/tasks/command_error.rb +5 -1
  18. data/lib/i18n/tasks/commands.rb +0 -1
  19. data/lib/i18n/tasks/configuration.rb +1 -9
  20. data/lib/i18n/tasks/console_context.rb +2 -2
  21. data/lib/i18n/tasks/data.rb +0 -1
  22. data/lib/i18n/tasks/data/adapter/json_adapter.rb +0 -1
  23. data/lib/i18n/tasks/data/adapter/yaml_adapter.rb +0 -1
  24. data/lib/i18n/tasks/data/file_formats.rb +0 -1
  25. data/lib/i18n/tasks/data/file_system.rb +0 -1
  26. data/lib/i18n/tasks/data/file_system_base.rb +0 -1
  27. data/lib/i18n/tasks/data/router/conservative_router.rb +0 -1
  28. data/lib/i18n/tasks/data/router/pattern_router.rb +0 -1
  29. data/lib/i18n/tasks/data/tree/node.rb +6 -7
  30. data/lib/i18n/tasks/data/tree/nodes.rb +0 -1
  31. data/lib/i18n/tasks/data/tree/siblings.rb +29 -10
  32. data/lib/i18n/tasks/data/tree/traversal.rb +0 -3
  33. data/lib/i18n/tasks/google_translation.rb +0 -1
  34. data/lib/i18n/tasks/ignore_keys.rb +0 -1
  35. data/lib/i18n/tasks/key_pattern_matching.rb +0 -1
  36. data/lib/i18n/tasks/logging.rb +0 -1
  37. data/lib/i18n/tasks/missing_keys.rb +0 -1
  38. data/lib/i18n/tasks/plural_keys.rb +0 -1
  39. data/lib/i18n/tasks/reports/base.rb +1 -2
  40. data/lib/i18n/tasks/reports/spreadsheet.rb +0 -1
  41. data/lib/i18n/tasks/reports/terminal.rb +41 -17
  42. data/lib/i18n/tasks/scanners/files/caching_file_finder.rb +32 -0
  43. data/lib/i18n/tasks/scanners/files/caching_file_finder_provider.rb +24 -0
  44. data/lib/i18n/tasks/scanners/files/caching_file_reader.rb +27 -0
  45. data/lib/i18n/tasks/scanners/files/file_finder.rb +61 -0
  46. data/lib/i18n/tasks/scanners/files/file_reader.rb +18 -0
  47. data/lib/i18n/tasks/scanners/key_occurrences.rb +35 -0
  48. data/lib/i18n/tasks/scanners/occurence.rb +50 -0
  49. data/lib/i18n/tasks/scanners/pattern_scanner.rb +97 -38
  50. data/lib/i18n/tasks/scanners/pattern_with_scope_scanner.rb +2 -3
  51. data/lib/i18n/tasks/scanners/relative_keys.rb +3 -4
  52. data/lib/i18n/tasks/scanners/scanner.rb +15 -0
  53. data/lib/i18n/tasks/scanners/scanner_multiplexer.rb +43 -0
  54. data/lib/i18n/tasks/unused_keys.rb +4 -5
  55. data/lib/i18n/tasks/used_keys.rb +76 -23
  56. data/lib/i18n/tasks/version.rb +1 -2
  57. data/spec/conservative_router_spec.rb +0 -1
  58. data/spec/file_system_data_spec.rb +0 -1
  59. data/spec/fixtures/app/controllers/events_controller.rb +1 -2
  60. data/spec/google_translate_spec.rb +0 -1
  61. data/spec/i18n_tasks_spec.rb +4 -15
  62. data/spec/key_pattern_matching_spec.rb +0 -1
  63. data/spec/locale_tree/siblings_spec.rb +0 -1
  64. data/spec/pattern_scanner_spec.rb +34 -36
  65. data/spec/plural_keys_spec.rb +0 -1
  66. data/spec/readme_spec.rb +0 -1
  67. data/spec/relative_keys_spec.rb +15 -10
  68. data/spec/scanners/files/caching_file_finder_provider_spec.rb +18 -0
  69. data/spec/scanners/files/caching_file_finder_spec.rb +39 -0
  70. data/spec/scanners/files/caching_file_reader_spec.rb +18 -0
  71. data/spec/scanners/files/file_finder_spec.rb +52 -0
  72. data/spec/scanners/files/file_reader_spec.rb +15 -0
  73. data/spec/scanners/scanner_multiplexer_spec.rb +26 -0
  74. data/spec/spec_helper.rb +1 -1
  75. data/spec/support/capture_std.rb +0 -1
  76. data/spec/support/fixtures.rb +0 -1
  77. data/spec/support/i18n_tasks_output_matcher.rb +0 -1
  78. data/spec/support/key_pattern_matcher.rb +0 -1
  79. data/spec/support/keys_and_occurrences.rb +27 -0
  80. data/spec/support/test_codebase.rb +0 -1
  81. data/spec/support/trees.rb +1 -7
  82. data/spec/used_keys_spec.rb +15 -16
  83. data/templates/config/i18n-tasks.yml +9 -2
  84. metadata +29 -9
  85. data/lib/i18n/tasks/scanners/base_scanner.rb +0 -149
  86. data/spec/commands/missing_commands_spec.rb +0 -23
@@ -1,17 +1,16 @@
1
- # coding: utf-8
2
1
  require 'set'
3
2
 
4
3
  module I18n
5
4
  module Tasks
6
5
  module UnusedKeys
7
- def unused_keys(opts = {})
8
- locales = Array(opts[:locales]).presence || self.locales
9
- locales.map { |locale| unused_tree locale, opts[:strict] }.compact.reduce(:merge!)
6
+ def unused_keys(locales: nil, strict: nil)
7
+ locales = Array(locales).presence || self.locales
8
+ locales.map { |locale| unused_tree(locale: locale, strict: strict) }.compact.reduce(:merge!)
10
9
  end
11
10
 
12
11
  # @param [String] locale
13
12
  # @param [Boolean] strict if true, do not match dynamic keys
14
- def unused_tree(locale = base_locale, strict = false)
13
+ def unused_tree(locale: base_locale, strict: nil)
15
14
  collapse_plural_nodes! data[locale].select_keys { |key, _node|
16
15
  !ignore_key?(key, :unused) &&
17
16
  (strict || !used_in_expr?(key)) &&
@@ -1,42 +1,95 @@
1
- # coding: utf-8
2
1
  require 'find'
3
2
  require 'i18n/tasks/scanners/pattern_with_scope_scanner'
3
+ require 'i18n/tasks/scanners/scanner_multiplexer'
4
+ require 'i18n/tasks/scanners/files/caching_file_finder_provider'
5
+ require 'i18n/tasks/scanners/files/caching_file_reader'
4
6
 
5
7
  module I18n::Tasks
6
8
  module UsedKeys
9
+ STRICT_DEFAULT = true
7
10
 
8
- # find all keys in the source (relative keys are absolutized)
9
- # @option opts [String] :key_filter
10
- # @option opts [Boolean] :strict if true dynamic keys are excluded (e.g. `t("category.#{category.key}")`)
11
- # @return [Array<String>]
12
- def used_tree(opts = {})
13
- return scanner.with_key_filter(opts[:key_filter]) { used_tree(opts.except(:key_filter)) } if opts[:key_filter]
11
+ # Find all keys in the source and return a forest with the keys in absolute form and their occurrences.
12
+ #
13
+ # @param key_filter [String] only return keys matching this pattern.
14
+ # @param strict [Boolean] if true, dynamic keys are excluded (e.g. `t("category.#{category.key}")`)
15
+ # @return [Data::Tree::Siblings]
16
+ def used_tree(key_filter: nil, strict: nil)
17
+ keys = scanner(strict: strict).keys
18
+ if key_filter
19
+ key_filter_re = compile_key_pattern(key_filter)
20
+ keys.select! { |k| k.key =~ key_filter_re }
21
+ end
14
22
  Data::Tree::Node.new(
15
- key: 'used',
16
- data: {key_filter: scanner.key_filter},
17
- children: Data::Tree::Siblings.from_key_attr(scanner.keys(opts.slice(:strict)))
23
+ key: 'used',
24
+ data: {key_filter: key_filter},
25
+ children: Data::Tree::Siblings.from_key_occurrences(keys)
18
26
  ).to_siblings
19
27
  end
20
28
 
21
- def scanner
22
- @scanner ||= begin
23
- search_config = (config[:search] || {}).with_indifferent_access
24
- class_name = search_config[:scanner] || '::I18n::Tasks::Scanners::PatternWithScopeScanner'
25
- ActiveSupport::Inflector.constantize(class_name).new search_config
29
+ def scanner(strict: nil)
30
+ (@scanner ||= {})[strict.nil? ? STRICT_DEFAULT : strict] ||= begin
31
+ config = search_config
32
+ config[:strict] = strict unless strict.nil?
33
+ Scanners::ScannerMultiplexer.new(
34
+ scanners: search_config[:scanners].map { |(class_name, args)|
35
+ ActiveSupport::Inflector.constantize(class_name).new(
36
+ config: search_config.deep_merge(args || {}),
37
+ file_finder_provider: caching_file_finder_provider,
38
+ file_reader: caching_file_reader)
39
+ })
26
40
  end
27
41
  end
28
42
 
29
- def used_key_names(strict = false)
30
- if strict
31
- @used_key_names ||= used_tree(strict: true).key_names
32
- else
33
- @used_key_names ||= used_tree.key_names
43
+ def search_config
44
+ @search_config ||= apply_default_scanner_config((config[:search] || {}).dup.deep_symbolize_keys)
45
+ end
46
+
47
+ def apply_default_scanner_config(conf)
48
+ conf[:strict] = STRICT_DEFAULT unless conf.key?(:strict)
49
+ if conf[:scanner]
50
+ warn_deprecated 'search.scanner is now search.scanners, an array of [ScannerClass, options]'
51
+ conf[:scanners] = [[conf.delete(:scanner)]]
34
52
  end
53
+ conf[:scanners] ||= [['::I18n::Tasks::Scanners::PatternWithScopeScanner']]
54
+ if conf[:relative_roots].blank?
55
+ conf[:relative_roots] = %w(app/controllers app/helpers app/mailers app/presenters app/views)
56
+ end
57
+ conf[:paths] = %w(app/) if conf[:paths].blank?
58
+ conf[:include] = Array(conf[:include]) if conf[:include].present?
59
+ conf[:exclude] = Array(conf[:exclude]) + %w(
60
+ *.jpg *.png *.gif *.svg *.ico *.eot *.otf *.ttf *.woff *.woff2 *.pdf *.css *.sass *.scss *.less *.yml *.json)
61
+ # Regexps for lines to ignore per extension
62
+ if conf[:ignore_lines] && !conf[:ignore_lines].is_a?(Hash)
63
+ warn_deprecated "search.ignore_lines must be a Hash, found #{conf[:ignore_lines].class.name}"
64
+ conf[:ignore_lines] = nil
65
+ end
66
+ conf[:ignore_lines] ||= {
67
+ 'rb' => %q(^\s*#(?!\si18n-tasks-use)),
68
+ 'opal' => %q(^\s*#(?!\si18n-tasks-use)),
69
+ 'haml' => %q(^\s*-\s*#(?!\si18n-tasks-use)),
70
+ 'slim' => %q(^\s*(?:-#|/)(?!\si18n-tasks-use)),
71
+ 'coffee' => %q(^\s*#(?!\si18n-tasks-use)),
72
+ 'erb' => %q(^\s*<%\s*#(?!\si18n-tasks-use)),
73
+ }
74
+ conf
75
+ end
76
+
77
+
78
+ def caching_file_finder_provider
79
+ @caching_file_finder_provider ||= Scanners::Files::CachingFileFinderProvider.new
80
+ end
81
+
82
+ def caching_file_reader
83
+ @caching_file_reader ||= Scanners::Files::CachingFileReader.new
84
+ end
85
+
86
+ def used_key_names(strict: nil)
87
+ (@used_key_names ||= {})[strict.nil? ? STRICT_DEFAULT : strict] ||= used_tree(strict: strict).key_names
35
88
  end
36
89
 
37
90
  # whether the key is used in the source
38
- def used_key?(key, strict = false)
39
- used_key_names(strict).include?(key)
91
+ def used_key?(key)
92
+ used_key_names(strict: true).include?(key)
40
93
  end
41
94
 
42
95
  # @return whether the key is potentially used in a code expression such as:
@@ -48,7 +101,7 @@ module I18n::Tasks
48
101
  # keys in the source that end with a ., e.g. t("category.#{cat.i18n_key}") or t("category." + category.key)
49
102
  def expr_key_re
50
103
  @expr_key_re ||= begin
51
- patterns = used_key_names.select { |k| key_expression?(k) }.map { |k|
104
+ patterns = used_key_names(strict: false).select { |k| key_expression?(k) }.map { |k|
52
105
  pattern = key_match_pattern(k)
53
106
  # disallow patterns with no keys
54
107
  next if pattern =~ /\A(:\.)*:\z/
@@ -1,6 +1,5 @@
1
- # coding: utf-8
2
1
  module I18n
3
2
  module Tasks
4
- VERSION = '0.8.7'
3
+ VERSION = '0.9.0.rc1'
5
4
  end
6
5
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  RSpec.describe 'Conservative router' do
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  RSpec.describe 'File system i18n' do
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  class EventsController < ApplicationController
3
2
  def create
4
3
  end
@@ -31,7 +30,7 @@ class EventsController < ApplicationController
31
30
  I18n.t "hash.#{stuff}.a"
32
31
 
33
32
  # relative key
34
- I18n.t(".success")
33
+ t(".success")
35
34
  end
36
35
 
37
36
  def update
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
  require 'i18n/tasks/commands'
4
3
 
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
  require 'fileutils'
4
3
  require 'open3'
@@ -10,6 +9,7 @@ RSpec.describe 'i18n-tasks' do
10
9
 
11
10
  describe 'bin/i18n-tasks' do
12
11
  it 'shows help when invoked with no arguments, shows version on --version' do
12
+ next if defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby'
13
13
  # These bin/i18n-tasks tests are executed in parallel for performance
14
14
  in_test_app_dir do
15
15
  [
@@ -23,7 +23,7 @@ RSpec.describe 'i18n-tasks' do
23
23
  expect(err).to include('greet')
24
24
  },
25
25
  proc {
26
- expect(%x[../../bin/i18n-tasks --version].chomp).to eq(I18n::Tasks::VERSION)
26
+ expect(%x[bundle exec ../../bin/i18n-tasks --version].chomp).to eq(I18n::Tasks::VERSION)
27
27
  }
28
28
  ].map { |test| Thread.start(&test) }.each(&:join)
29
29
  end
@@ -98,8 +98,8 @@ RSpec.describe 'i18n-tasks' do
98
98
  end
99
99
 
100
100
  describe 'unused' do
101
- it 'detects unused' do
102
- out, result = run_cmd_capture_stdout_and_result 'unused'
101
+ it 'detects unused (--no-strict)' do
102
+ out, result = run_cmd_capture_stdout_and_result('unused', '--no-strict')
103
103
  expect(result).to eq :exit_1
104
104
  expect(out).to be_i18n_keys expected_unused_keys
105
105
  end
@@ -211,17 +211,6 @@ RSpec.describe 'i18n-tasks' do
211
211
  expect(YAML.load_file('config/locales/en.yml')['en']['present_in_es_but_not_en']['a']).to eq 'TRME ES_TEXT'
212
212
  }
213
213
  end
214
-
215
- it '--value with %{key}' do
216
- in_test_app_dir {
217
- expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']).to be_nil
218
- }
219
- run_cmd 'add-missing', '-v', 'TRME %{key}'
220
- in_test_app_dir {
221
- expect(YAML.load_file('config/locales/es.yml')['es']['missing_in_es']['a']).to eq 'TRME es.missing_in_es.a'
222
- expect(YAML.load_file('config/locales/en.yml')['en']['present_in_es_but_not_en']['a']).to eq 'TRME en.present_in_es_but_not_en.a'
223
- }
224
- end
225
214
  end
226
215
 
227
216
  describe 'config' do
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  RSpec.describe 'Key pattern' do
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  RSpec.describe 'Tree siblings / forest' do
@@ -1,49 +1,47 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
- RSpec.describe 'Pattern Scanner' do
5
- describe 'scan_file' do
3
+ RSpec.describe 'PatternScanner' do
4
+ describe '#keys' do
5
+ let(:expected_key) {
6
+ 'events.show.success'
7
+ }
8
+
9
+ let(:expected_occurrence) {
10
+ {path: 'spec/fixtures/app/controllers/events_controller.rb',
11
+ pos: 769,
12
+ line_num: 33,
13
+ line_pos: 5,
14
+ line: ' t(".success")'}
15
+ }
16
+
6
17
  it 'returns absolute keys from controllers' do
7
18
  file_path = 'spec/fixtures/app/controllers/events_controller.rb'
8
- scanner = I18n::Tasks::Scanners::PatternScanner.new
19
+ scanner = I18n::Tasks::Scanners::PatternScanner.new(
20
+ config: {paths: ['spec/fixtures/'], include: [file_path], relative_roots: ['spec/fixtures/app/controllers']})
9
21
  allow(scanner).to receive(:relative_roots).and_return(['spec/fixtures/app/controllers'])
10
-
11
- keys = scanner.scan_file(file_path)
12
-
13
- expect(keys).to include(
14
- ["events.show.success",
15
- {:data=>
16
- {
17
- :src_path=>"spec/fixtures/app/controllers/events_controller.rb",
18
- :pos=>790,
19
- :line_num=>34,
20
- :line_pos=>10,
21
- :line =>" I18n.t(\".success\")"}
22
- }
23
- ]
24
- )
22
+ expect(scanner.keys.detect { |key_occurrences| key_occurrences.key =~ /success/ }).to(
23
+ eq make_key_occurrences(expected_key, [expected_occurrence]))
25
24
  end
26
25
  end
27
26
 
28
27
  describe 'default_pattern' do
29
- let!(:pattern) { I18n::Tasks::Scanners::PatternScanner.new.default_pattern }
28
+ let!(:pattern) { I18n::Tasks::Scanners::PatternScanner.new.send(:default_pattern) }
30
29
 
31
- [
32
- 't(".a.b")',
33
- 't "a.b"',
34
- "t 'a.b'",
35
- 't("a.b")',
36
- "t('a.b')",
37
- "t('a.b', :arg => val)",
38
- "t('a.b', arg: val)",
39
- "t :a_b",
40
- "t :'a.b'",
41
- 't :"a.b"',
42
- "t(:ab)",
43
- "t(:'a.b')",
44
- 't(:"a.b")',
45
- 'I18n.t("a.b")',
46
- 'I18n.translate("a.b")'
30
+ ['t(".a.b")',
31
+ 't "a.b"',
32
+ "t 'a.b'",
33
+ 't("a.b")',
34
+ "t('a.b')",
35
+ "t('a.b', :arg => val)",
36
+ "t('a.b', arg: val)",
37
+ "t :a_b",
38
+ "t :'a.b'",
39
+ 't :"a.b"',
40
+ "t(:ab)",
41
+ "t(:'a.b')",
42
+ 't(:"a.b")',
43
+ 'I18n.t("a.b")',
44
+ 'I18n.translate("a.b")'
47
45
  ].each do |string|
48
46
  it "matches #{string}" do
49
47
  expect(pattern).to match string
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
3
2
 
4
3
  RSpec.describe 'Plural keys' do
data/spec/readme_spec.rb CHANGED
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
 
3
2
  RSpec.describe 'README.md' do
4
3
  let(:readme) { File.read('README.md', encoding: 'UTF-8') }
@@ -1,25 +1,30 @@
1
- # coding: utf-8
2
1
  require 'spec_helper'
2
+ require 'i18n/tasks/scanners/relative_keys'
3
+
3
4
  RSpec.describe 'Relative keys' do
4
- let(:scanner) { I18n::Tasks::Scanners::BaseScanner.new }
5
+ class RelativeKeysUser
6
+ include ::I18n::Tasks::Scanners::RelativeKeys
7
+ end
8
+
9
+ let(:relative_keys) { RelativeKeysUser.new }
5
10
 
6
11
  describe 'absolutize_key' do
7
12
 
8
13
  context 'default settings' do
9
14
  it 'works' do
10
- expect(scanner.absolutize_key('.title', 'app/views/movies/show.html.slim', %w(app/views))).to eq('movies.show.title')
15
+ expect(relative_keys.absolutize_key('.title', 'app/views/movies/show.html.slim', %w(app/views))).to eq('movies.show.title')
11
16
  end
12
17
  end
13
18
 
14
19
  context 'custom roots' do
15
20
  it 'works' do
16
- expect(scanner.absolutize_key('.title', 'app/views-mobile/movies/show.html.slim', %w(app/views app/views-mobile))).to eq('movies.show.title')
21
+ expect(relative_keys.absolutize_key('.title', 'app/views-mobile/movies/show.html.slim', %w(app/views app/views-mobile))).to eq('movies.show.title')
17
22
  end
18
23
  end
19
24
 
20
25
  context 'relative key in controller' do
21
26
  it 'works' do
22
- key = scanner.absolutize_key(
27
+ key = relative_keys.absolutize_key(
23
28
  '.success',
24
29
  'app/controllers/users_controller.rb',
25
30
  %w(app/controllers),
@@ -31,7 +36,7 @@ RSpec.describe 'Relative keys' do
31
36
 
32
37
  context 'multiple words in controller name' do
33
38
  it 'works' do
34
- key = scanner.absolutize_key(
39
+ key = relative_keys.absolutize_key(
35
40
  '.success',
36
41
  'app/controllers/admin_users_controller.rb',
37
42
  %w(app/controllers),
@@ -44,7 +49,7 @@ RSpec.describe 'Relative keys' do
44
49
 
45
50
  context 'nested in module' do
46
51
  it 'works' do
47
- key = scanner.absolutize_key(
52
+ key = relative_keys.absolutize_key(
48
53
  '.success',
49
54
  'app/controllers/nested/users_controller.rb',
50
55
  %w(app/controllers),
@@ -58,7 +63,7 @@ RSpec.describe 'Relative keys' do
58
63
 
59
64
  context 'relative key in mailer' do
60
65
  it 'works' do
61
- key = scanner.absolutize_key(
66
+ key = relative_keys.absolutize_key(
62
67
  '.subject',
63
68
  'app/mailers/user_mailer.rb',
64
69
  %w(app/mailers),
@@ -70,7 +75,7 @@ RSpec.describe 'Relative keys' do
70
75
 
71
76
  context 'multiple words in mailer name' do
72
77
  it 'works' do
73
- key = scanner.absolutize_key(
78
+ key = relative_keys.absolutize_key(
74
79
  '.subject',
75
80
  'app/mailers/admin_user_mailer.rb',
76
81
  %w(app/mailers),
@@ -83,7 +88,7 @@ RSpec.describe 'Relative keys' do
83
88
 
84
89
  context 'nested in module' do
85
90
  it 'works' do
86
- key = scanner.absolutize_key(
91
+ key = relative_keys.absolutize_key(
87
92
  '.subject',
88
93
  'app/mailers/nested/user_mailer.rb',
89
94
  %w(app/mailers),
@@ -0,0 +1,18 @@
1
+ require 'spec_helper'
2
+ require 'i18n/tasks/scanners/files/caching_file_finder_provider'
3
+
4
+ RSpec.describe 'CachingFileFinderProvider' do
5
+ describe '#get' do
6
+ it 'provides the same instance for the same arguments' do
7
+ provider = I18n::Tasks::Scanners::Files::CachingFileFinderProvider.new
8
+ expect(provider.get(include: ['./a'])).to(
9
+ be(provider.get(include: ['./a'])))
10
+ end
11
+
12
+ it 'provides different instances for different arguments' do
13
+ provider = I18n::Tasks::Scanners::Files::CachingFileFinderProvider.new
14
+ expect(provider.get(include: ['./a'])).to_not(
15
+ be(provider.get(include: ['./b'])))
16
+ end
17
+ end
18
+ end