i18n-tasks 0.8.7 → 0.9.0.rc1

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 (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