i18n-active_record 0.4.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d742b8d5877fc39c8855a29b4cd864732b750f3167567ced3dcd3bf2e9ad3d25
4
- data.tar.gz: e6f0df2b6ff56a75568c44e11c7e19e6a5e161352308247e12afeb8ffd294522
3
+ metadata.gz: 9a66ea934bb11309eb79e45fe45b206f596aecdef52de87d193b8d9ec9a8ac54
4
+ data.tar.gz: 92f91630acf638a76c02a527142c51565c8422bf1a9443254ba8eeca1a6ad0f8
5
5
  SHA512:
6
- metadata.gz: 7fba006f4b5feb3d33cc9917a8c487d11b33e1bdfc64dff8e78e52f909393a0ee86b5a820b674f1b69ad28223459a336dba509fd1cf7f4a9eecbcf922ba4b86c
7
- data.tar.gz: b8e8a9b39d0d531d0cea78034372f2ac46dedfe1a66269bd9aa72738dcc82544b307222aa603dd1037874a1609f9cb592f7349de4d879aca3c4a4f74f67736d4
6
+ metadata.gz: 6683c1ff6494df8ef79f0d96398842e0315a1a66d6850d0abc13157de0b45faa9728121c55459ccfa78ad70497faab5a084e2e64ad53d148647ad5fbe4fda433
7
+ data.tar.gz: 2699f7f14fd099990a227ee9cf5e8bd5a1d65957f2e752fcda2624220dfabc470c13b4c4f5f561578d2a79becf67dbc015517656a0f62d52d3e17f4c7f52d2bd
data/README.md CHANGED
@@ -1,7 +1,7 @@
1
- # I18n::Backend::ActiveRecord
1
+ # I18n::Backend::ActiveRecord [![Ruby Style Guide](https://img.shields.io/badge/code_style-rubocop-brightgreen.svg)](https://github.com/rubocop/rubocop) [![Tests Status](https://github.com/svenfuchs/i18n-active_record/actions/workflows/test.yml/badge.svg)](https://github.com/svenfuchs/i18n-active_record/actions) [![Linter Status](https://github.com/svenfuchs/i18n-active_record/actions/workflows/linter.yml/badge.svg)](https://github.com/svenfuchs/i18n-active_record/actions)
2
2
 
3
- This repository contains the I18n ActiveRecord backend and support code that has been extracted from the "I18n": http://github.com/svenfuchs/i18n.
4
- It is fully compatible with Rails 3, 4, 5 and 6.
3
+ This repository contains the I18n ActiveRecord backend and support code that has been extracted from the `I18n` gem: http://github.com/svenfuchs/i18n.
4
+ It is fully compatible with Rails 4, 5 and 6.
5
5
 
6
6
  ## Installation
7
7
 
@@ -45,7 +45,7 @@ By default the installer creates a new file in `config/initializers` named `i18n
45
45
  ```ruby
46
46
  require 'i18n/backend/active_record'
47
47
 
48
- Translation = I18n::Backend::ActiveRecord::Translation
48
+ Translation = I18n::Backend::ActiveRecord::Translation
49
49
 
50
50
  if Translation.table_exists?
51
51
  I18n.backend = I18n::Backend::ActiveRecord.new
@@ -77,11 +77,37 @@ I18n::Backend::ActiveRecord.configure do |config|
77
77
  end
78
78
  ```
79
79
 
80
+ To configure the ActiveRecord backend to cache translations(might be useful in production) use:
81
+
82
+ ```ruby
83
+ I18n::Backend::ActiveRecord.configure do |config|
84
+ config.cache_translations = true # defaults to false
85
+ end
86
+ ```
87
+
80
88
  ## Usage
81
89
 
82
90
  You can now use `I18n.t('Your String')` to lookup translations in the database.
83
91
 
84
- ## Missing Translations -> Interpolations
92
+ ## Missing Translations
93
+
94
+ ### Usage
95
+
96
+ In order to make the `I18n::Backend::ActiveRecord::Missing` module working correctly pluralization rules should be configured properly.
97
+ The `i18n.plural.keys` translation key should be present in any of the backends.
98
+ See https://github.com/svenfuchs/i18n-active_record/blob/master/lib/i18n/backend/active_record/missing.rb for more information.
99
+
100
+ ```yaml
101
+ en:
102
+ i18n:
103
+ plural:
104
+ keys:
105
+ - :zero
106
+ - :one
107
+ - :other
108
+ ```
109
+
110
+ ### Interpolations
85
111
 
86
112
  The `interpolations` field in the `translations` table is used by `I18n::Backend::ActiveRecord::Missing` to store the interpolations seen the first time this Translation was requested. This will help translators understand what interpolations to expect, and thus to include when providing the translations.
87
113
 
@@ -91,6 +117,23 @@ The `interpolations` field is otherwise unused since the "value" in `Translation
91
117
 
92
118
  * http://collectiveidea.com/blog/archives/2016/05/31/beyond-yml-files-dynamic-translations/
93
119
 
120
+ ## Contributing
121
+
122
+ ### Test suite
123
+
124
+ The test suite can be run with:
125
+
126
+ bundle exec rake
127
+
128
+ By default it runs the tests for SQLite database, to specify a database the `DB` env variable can be used:
129
+
130
+ DB=postgres bundle exec rake
131
+ DB=mysql bundle exec rake
132
+
133
+ To run tests for a specific rails version see [Appraisal](https://github.com/thoughtbot/appraisal):
134
+
135
+ bundle exec appraisal rails-4 rake test
136
+
94
137
  ## Maintainers
95
138
 
96
139
  * Sven Fuchs
data/Rakefile CHANGED
@@ -1,66 +1,12 @@
1
- require 'rake'
1
+ # frozen_string_literal: true
2
+
2
3
  require 'rake/testtask'
3
4
  require 'bundler/gem_tasks'
4
5
 
5
- def execute(command)
6
- puts command
7
- system command
8
- end
9
-
10
- def bundle_options
11
- return '' unless ENV['BUNDLE_GEMFILE']
12
-
13
- "--gemfile #{ENV['BUNDLE_GEMFILE']}"
14
- end
15
-
16
- def each_database(&block)
17
- ['sqlite', 'postgres', 'mysql'].each &block
18
- end
19
-
20
- namespace :bundle do
21
- task :env do
22
- ar = ENV['AR'].to_s
23
-
24
- next if ar.empty?
25
-
26
- gemfile = "gemfiles/Gemfile.rails_#{ar}"
27
- raise "Cannot find gemfile at #{gemfile}" unless File.exist?(gemfile)
28
-
29
- ENV['BUNDLE_GEMFILE'] = gemfile
30
- puts "Using gemfile: #{gemfile}"
31
- end
32
-
33
- task install: :env do
34
- execute "bundle install #{bundle_options}"
35
- end
36
-
37
- task update: :env do
38
- execute "bundle update #{bundle_options}"
39
- end
40
-
41
- task :install_all do
42
- [nil, '3', '4', '5', '6', 'head'].each do |ar|
43
- opt = ar && "AR=#{ar}"
44
- execute "rake bundle:install #{opt}"
45
- end
46
- end
47
- end
48
-
49
- task :test do
50
- each_database { |db| execute "rake #{db}:test" }
51
- end
52
-
53
- Rake::TestTask.new :_test do |t|
6
+ Rake::TestTask.new :test do |t|
54
7
  t.libs << 'test'
55
8
  t.pattern = 'test/**/*_test.rb'
56
9
  t.verbose = false
57
10
  end
58
11
 
59
- each_database do |db|
60
- namespace db do
61
- task(:env) { ENV['DB'] = db }
62
- task test: ['env', 'bundle:env', '_test']
63
- end
64
- end
65
-
66
12
  task default: :test
@@ -1,10 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'rails/generators/active_record'
2
4
 
3
5
  module I18n
4
6
  module ActiveRecord
5
7
  module Generators
6
8
  class InstallGenerator < ::ActiveRecord::Generators::Base
7
- desc "Installs i18n-active_record and generates the necessary migrations"
9
+ desc 'Installs i18n-active_record and generates the necessary migrations'
8
10
 
9
11
  argument :name, type: :string, default: 'Translation'
10
12
 
@@ -13,5 +13,6 @@ if Translation.table_exists?
13
13
  end
14
14
 
15
15
  I18n::Backend::ActiveRecord.configure do |config|
16
+ # config.cache_translations = true # defaults to false
16
17
  # config.cleanup_with_destroy = true # defaults to false
17
18
  end
@@ -2,5 +2,6 @@ require 'i18n/backend/active_record'
2
2
  I18n.backend = I18n::Backend::ActiveRecord.new
3
3
 
4
4
  I18n::Backend::ActiveRecord.configure do |config|
5
+ # config.cache_translations = true # defaults to false
5
6
  # config.cleanup_with_destroy = true # defaults to false
6
7
  end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module I18n
2
4
  module ActiveRecord
3
- VERSION = '0.4.1'
5
+ VERSION = '1.0.0'
4
6
  end
5
7
  end
@@ -1 +1,3 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'i18n'
@@ -1,11 +1,14 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module I18n
2
4
  module Backend
3
5
  class ActiveRecord
4
6
  class Configuration
5
- attr_accessor :cleanup_with_destroy
7
+ attr_accessor :cleanup_with_destroy, :cache_translations
6
8
 
7
9
  def initialize
8
10
  @cleanup_with_destroy = false
11
+ @cache_translations = false
9
12
  end
10
13
  end
11
14
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This extension stores translation stub records for missing translations to
2
4
  # the database.
3
5
  #
@@ -36,27 +38,28 @@ module I18n
36
38
  include Flatten
37
39
 
38
40
  def store_default_translations(locale, key, options = {})
39
- count, scope, default, separator = options.values_at(:count, :scope, :default, :separator)
41
+ count, scope, _, separator = options.values_at(:count, :scope, :default, :separator)
40
42
  separator ||= I18n.default_separator
41
43
  key = normalize_flat_keys(locale, key, scope, separator)
42
44
 
43
- unless ActiveRecord::Translation.locale(locale).lookup(key).exists?
44
- interpolations = options.keys - I18n::RESERVED_KEYS
45
- keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]
46
- keys.each { |key| store_default_translation(locale, key, interpolations) }
47
- end
45
+ return if ActiveRecord::Translation.locale(locale).lookup(key).exists?
46
+
47
+ interpolations = options.keys - I18n::RESERVED_KEYS
48
+ keys = count ? I18n.t('i18n.plural.keys', locale: locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]
49
+ keys.each { |k| store_default_translation(locale, k, interpolations) }
48
50
  end
49
51
 
50
52
  def store_default_translation(locale, key, interpolations)
51
- translation = ActiveRecord::Translation.new :locale => locale.to_s, :key => key
53
+ translation = ActiveRecord::Translation.new locale: locale.to_s, key: key
52
54
  translation.interpolations = interpolations
53
55
  translation.save
54
56
  end
55
57
 
56
58
  def translate(locale, key, options = {})
57
59
  result = catch(:exception) { super }
60
+
58
61
  if result.is_a?(I18n::MissingTranslation)
59
- self.store_default_translations(locale, key, options)
62
+ store_default_translations(locale, key, options)
60
63
  throw(:exception, result)
61
64
  else
62
65
  result
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # This module is intended to be mixed into the ActiveRecord backend to allow
2
4
  # storing Ruby Procs as translation values in the database.
3
5
  #
@@ -21,13 +23,13 @@ module I18n
21
23
  module Backend
22
24
  class ActiveRecord
23
25
  module StoreProcs
24
- def value=(v)
25
- case v
26
+ def value=(val)
27
+ case val
26
28
  when Proc
27
- write_attribute(:value, v.to_ruby)
29
+ write_attribute(:value, val.to_ruby)
28
30
  write_attribute(:is_proc, true)
29
31
  else
30
- write_attribute(:value, v)
32
+ write_attribute(:value, val)
31
33
  end
32
34
  end
33
35
 
@@ -36,4 +38,3 @@ module I18n
36
38
  end
37
39
  end
38
40
  end
39
-
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'active_record'
2
4
 
3
5
  module I18n
@@ -53,19 +55,20 @@ module I18n
53
55
 
54
56
  serialize :value
55
57
  serialize :interpolations, Array
58
+ after_commit :invalidate_translations_cache
56
59
 
57
60
  class << self
58
61
  def locale(locale)
59
- where(:locale => locale.to_s)
62
+ where(locale: locale.to_s)
60
63
  end
61
64
 
62
65
  def lookup(keys, *separator)
63
66
  column_name = connection.quote_column_name('key')
64
- keys = Array(keys).map! { |key| key.to_s }
67
+ keys = Array(keys).map!(&:to_s)
65
68
 
66
69
  unless separator.empty?
67
- warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " <<
68
- "You can change the internal separator by overwriting FLATTEN_SEPARATOR."
70
+ warn '[DEPRECATION] Giving a separator to Translation.lookup is deprecated. ' \
71
+ 'You can change the internal separator by overwriting FLATTEN_SEPARATOR.'
69
72
  end
70
73
 
71
74
  namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%"
@@ -83,14 +86,14 @@ module I18n
83
86
  keys.each.with_index.inject(locale_hash) do |iterator, (key_part, index)|
84
87
  key = key_part.to_sym
85
88
  iterator[key] = keys[index + 1] ? (iterator[key] || {}) : t.value
86
- iterator[key]
89
+ iterator[key] # rubocop:disable Lint/UnmodifiedReduceAccumulator
87
90
  end
88
91
  end
89
92
  end
90
93
  end
91
94
 
92
95
  def interpolates?(key)
93
- self.interpolations.include?(key) if self.interpolations
96
+ interpolations&.include?(key)
94
97
  end
95
98
 
96
99
  def value
@@ -107,14 +110,19 @@ module I18n
107
110
  end
108
111
 
109
112
  def value=(value)
110
- if value === false
113
+ case value
114
+ when false
111
115
  value = FALSY_CHAR
112
- elsif value === true
116
+ when true
113
117
  value = TRUTHY_CHAR
114
118
  end
115
119
 
116
120
  write_attribute(:value, value)
117
121
  end
122
+
123
+ def invalidate_translations_cache
124
+ I18n.backend.reload! if I18n::Backend::ActiveRecord.config.cache_translations
125
+ end
118
126
  end
119
127
  end
120
128
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'i18n/backend/base'
2
4
  require 'i18n/backend/active_record/translation'
3
5
 
@@ -9,6 +11,9 @@ module I18n
9
11
  autoload :Translation, 'i18n/backend/active_record/translation'
10
12
  autoload :Configuration, 'i18n/backend/active_record/configuration'
11
13
 
14
+ include Base
15
+ include Flatten
16
+
12
17
  class << self
13
18
  def configure
14
19
  yield(config) if block_given?
@@ -19,103 +24,111 @@ module I18n
19
24
  end
20
25
  end
21
26
 
22
- module Implementation
23
- include Base, Flatten
27
+ def initialize(*args)
28
+ super
24
29
 
25
- def available_locales
26
- begin
27
- Translation.available_locales
28
- rescue ::ActiveRecord::StatementInvalid
29
- []
30
- end
31
- end
30
+ reload!
31
+ end
32
32
 
33
- def store_translations(locale, data, options = {})
34
- escape = options.fetch(:escape, true)
35
- flatten_translations(locale, data, escape, false).each do |key, value|
36
- translation = Translation.locale(locale).lookup(expand_keys(key))
33
+ def available_locales
34
+ Translation.available_locales
35
+ rescue ::ActiveRecord::StatementInvalid
36
+ []
37
+ end
38
+
39
+ def store_translations(locale, data, options = {})
40
+ escape = options.fetch(:escape, true)
37
41
 
38
- if ActiveRecord.config.cleanup_with_destroy
39
- translation.destroy_all
40
- else
41
- translation.delete_all
42
- end
42
+ flatten_translations(locale, data, escape, false).each do |key, value|
43
+ translation = Translation.locale(locale).lookup(expand_keys(key))
43
44
 
44
- Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value)
45
+ if ActiveRecord.config.cleanup_with_destroy
46
+ translation.destroy_all
47
+ else
48
+ translation.delete_all
45
49
  end
46
- end
47
50
 
48
- def reload!
49
- @translations = nil
50
- self
51
+ Translation.create(locale: locale.to_s, key: key.to_s, value: value)
51
52
  end
52
53
 
53
- def initialized?
54
- !@translations.nil?
55
- end
54
+ reload! if ActiveRecord.config.cache_translations
55
+ end
56
56
 
57
- def init_translations
58
- @translations = Translation.to_hash
59
- end
57
+ def reload!
58
+ @translations = nil
60
59
 
61
- def translations(do_init: false)
62
- init_translations if do_init || !initialized?
63
- @translations ||= {}
64
- end
60
+ self
61
+ end
62
+
63
+ def initialized?
64
+ !@translations.nil?
65
+ end
66
+
67
+ def init_translations
68
+ @translations = Translation.to_hash
69
+ end
70
+
71
+ def translations(do_init: false)
72
+ init_translations if do_init || !initialized?
73
+ @translations ||= {}
74
+ end
65
75
 
66
76
  protected
67
77
 
68
- def lookup(locale, key, scope = [], options = {})
69
- key = normalize_flat_keys(locale, key, scope, options[:separator])
70
- if key.first == '.'
71
- key = key[1..-1]
72
- end
73
- if key.last == '.'
74
- key = key[0..-2]
75
- end
78
+ def lookup(locale, key, scope = [], options = {})
79
+ key = normalize_flat_keys(locale, key, scope, options[:separator])
80
+ key = key[1..-1] if key.first == '.'
81
+ key = key[0..-2] if key.last == '.'
76
82
 
77
- result = if key == ''
78
- Translation.locale(locale).all
79
- else
80
- Translation.locale(locale).lookup(key)
81
- end
83
+ if ActiveRecord.config.cache_translations
84
+ init_translations if @translations.nil? || @translations.empty?
82
85
 
83
- if result.empty?
84
- nil
85
- elsif result.first.key == key
86
- result.first.value
87
- else
88
- result = result.inject({}) do |hash, translation|
89
- hash.deep_merge build_translation_hash_by_key(key, translation)
90
- end
91
- result.deep_symbolize_keys
92
- end
86
+ keys = ([locale] + key.split(I18n::Backend::Flatten::FLATTEN_SEPARATOR)).map(&:to_sym)
87
+
88
+ return translations.dig(*keys)
93
89
  end
94
90
 
95
- def build_translation_hash_by_key(lookup_key, translation)
96
- hash = {}
97
- if lookup_key == ''
98
- chop_range = 0..-1
99
- else
100
- chop_range = (lookup_key.size + FLATTEN_SEPARATOR.size)..-1
101
- end
102
- translation_nested_keys = translation.key.slice(chop_range).split(FLATTEN_SEPARATOR)
103
- translation_nested_keys.each.with_index.inject(hash) do |iterator, (key, index)|
104
- iterator[key] = translation_nested_keys[index + 1] ? {} : translation.value
105
- iterator[key]
106
- end
107
- hash
91
+ result = if key == ''
92
+ Translation.locale(locale).all
93
+ else
94
+ Translation.locale(locale).lookup(key)
108
95
  end
109
96
 
110
- # For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
111
- def expand_keys(key)
112
- key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, key|
113
- keys << [keys.last, key].compact.join(FLATTEN_SEPARATOR)
97
+ if result.empty?
98
+ nil
99
+ elsif result.first.key == key
100
+ result.first.value
101
+ else
102
+ result = result.inject({}) do |hash, translation|
103
+ hash.deep_merge build_translation_hash_by_key(key, translation)
114
104
  end
105
+ result.deep_symbolize_keys
115
106
  end
116
107
  end
117
108
 
118
- include Implementation
109
+ def build_translation_hash_by_key(lookup_key, translation)
110
+ hash = {}
111
+
112
+ chop_range = if lookup_key == ''
113
+ 0..-1
114
+ else
115
+ (lookup_key.size + FLATTEN_SEPARATOR.size)..-1
116
+ end
117
+ translation_nested_keys = translation.key.slice(chop_range).split(FLATTEN_SEPARATOR)
118
+ translation_nested_keys.each.with_index.inject(hash) do |iterator, (key, index)|
119
+ iterator[key] = translation_nested_keys[index + 1] ? {} : translation.value
120
+ iterator[key]
121
+ end
122
+
123
+ hash
124
+ end
125
+
126
+ # For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
127
+ def expand_keys(key)
128
+ key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, k|
129
+ keys << [keys.last, k].compact.join(FLATTEN_SEPARATOR)
130
+ end
131
+ end
119
132
  end
120
133
  end
121
134
  end
@@ -1,136 +1,166 @@
1
- require_relative './test_helper'
1
+ # frozen_string_literal: true
2
+
3
+ require 'test_helper'
2
4
 
3
5
  class I18nBackendActiveRecordTest < I18n::TestCase
4
6
  def setup
7
+ super
8
+
9
+ I18n::Backend::ActiveRecord::Translation.destroy_all
5
10
  I18n.backend = I18n::Backend::ActiveRecord.new
6
- store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
11
+
12
+ store_translations(:en, foo: { bar: 'bar', baz: 'baz' })
7
13
  end
8
14
 
9
15
  def teardown
10
- I18n::Backend::ActiveRecord::Translation.destroy_all
11
16
  I18n::Backend::ActiveRecord.instance_variable_set :@config, I18n::Backend::ActiveRecord::Configuration.new
17
+
12
18
  super
13
19
  end
14
20
 
15
- test "store_translations does not allow ambiguous keys (1)" do
16
- I18n::Backend::ActiveRecord::Translation.delete_all
17
- I18n.backend.store_translations(:en, :foo => 'foo')
18
- I18n.backend.store_translations(:en, :foo => { :bar => 'bar' })
19
- I18n.backend.store_translations(:en, :foo => { :baz => 'baz' })
21
+ class WithoutCacheTest < I18nBackendActiveRecordTest
22
+ def setup
23
+ super
20
24
 
21
- translations = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').all
22
- assert_equal %w(bar baz), translations.map(&:value)
25
+ I18n::Backend::ActiveRecord.config.cache_translations = false
26
+ end
23
27
 
24
- assert_equal({ :bar => 'bar', :baz => 'baz' }, I18n.t(:foo))
25
- end
28
+ test 'store_translations does not allow ambiguous keys (1)' do
29
+ store_translations(:en, foo: 'foo')
30
+ store_translations(:en, foo: { bar: 'bar' })
31
+ store_translations(:en, foo: { baz: 'baz' })
26
32
 
27
- test "store_translations does not allow ambiguous keys (2)" do
28
- I18n::Backend::ActiveRecord::Translation.delete_all
29
- I18n.backend.store_translations(:en, :foo => { :bar => 'bar' })
30
- I18n.backend.store_translations(:en, :foo => { :baz => 'baz' })
31
- I18n.backend.store_translations(:en, :foo => 'foo')
33
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').all
34
+ assert_equal %w[bar baz], translations.map(&:value)
32
35
 
33
- translations = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').all
34
- assert_equal %w(foo), translations.map(&:value)
36
+ assert_equal({ bar: 'bar', baz: 'baz' }, I18n.t(:foo))
37
+ end
35
38
 
36
- assert_equal 'foo', I18n.t(:foo)
37
- end
39
+ test 'store_translations does not allow ambiguous keys (2)' do
40
+ store_translations(:en, foo: { bar: 'bar' })
41
+ store_translations(:en, foo: { baz: 'baz' })
42
+ store_translations(:en, foo: 'foo')
38
43
 
39
- test "can store translations with keys that are translations containing special chars" do
40
- I18n.backend.store_translations(:es, :"Pagina's" => "Pagina's" )
41
- assert_equal "Pagina's", I18n.t(:"Pagina's", :locale => :es)
42
- end
44
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').all
45
+ assert_equal %w[foo], translations.map(&:value)
43
46
 
44
- test "missing translations table does not cause an error in #available_locales" do
45
- I18n::Backend::ActiveRecord::Translation.expects(:available_locales).raises(::ActiveRecord::StatementInvalid, 'msg')
46
- assert_equal [], I18n.backend.available_locales
47
- end
47
+ assert_equal 'foo', I18n.t(:foo)
48
+ end
48
49
 
49
- test "expand_keys" do
50
- assert_equal %w(foo foo.bar foo.bar.baz), I18n.backend.send(:expand_keys, :'foo.bar.baz')
51
- end
50
+ test 'can store translations with keys that are translations containing special chars' do
51
+ store_translations(:es, "Pagina's": "Pagina's")
52
52
 
53
- test "available_locales returns uniq locales" do
54
- I18n::Backend::ActiveRecord::Translation.delete_all
55
- I18n.backend.store_translations(:en, :foo => { :bar => 'bar' })
56
- I18n.backend.store_translations(:en, :foo => { :baz => 'baz' })
57
- I18n.backend.store_translations(:de, :foo1 => 'foo')
58
- I18n.backend.store_translations(:de, :foo2 => 'foo')
59
- I18n.backend.store_translations(:uk, :foo3 => 'foo')
60
-
61
- available_locales = I18n::Backend::ActiveRecord::Translation.available_locales
62
- assert_equal 3, available_locales.size
63
- assert_includes available_locales, :en
64
- assert_includes available_locales, :de
65
- assert_includes available_locales, :uk
66
- end
53
+ assert_equal "Pagina's", I18n.t(:"Pagina's", locale: :es)
54
+ end
67
55
 
68
- test "the default configuration has cleanup_with_destroy == false" do
69
- refute I18n::Backend::ActiveRecord.config.cleanup_with_destroy
70
- end
56
+ test 'missing translations table does not cause an error in #available_locales' do
57
+ I18n::Backend::ActiveRecord::Translation
58
+ .expects(:available_locales)
59
+ .raises(::ActiveRecord::StatementInvalid, 'msg')
60
+ assert_equal [], I18n.backend.available_locales
61
+ end
71
62
 
72
- test "the configuration supports cleanup_with_destroy being set" do
73
- I18n::Backend::ActiveRecord.configure do |config|
74
- config.cleanup_with_destroy = true
63
+ test 'expand_keys' do
64
+ assert_equal %w[foo foo.bar foo.bar.baz], I18n.backend.send(:expand_keys, :'foo.bar.baz')
75
65
  end
76
66
 
77
- assert I18n::Backend::ActiveRecord.config.cleanup_with_destroy
78
- end
67
+ test 'available_locales returns uniq locales' do
68
+ store_translations(:en, foo: { bar: 'bar' })
69
+ store_translations(:en, foo: { baz: 'baz' })
70
+ store_translations(:de, foo1: 'foo')
71
+ store_translations(:de, foo2: 'foo')
72
+ store_translations(:uk, foo3: 'foo')
73
+
74
+ available_locales = I18n::Backend::ActiveRecord::Translation.available_locales
75
+ assert_equal 3, available_locales.size
76
+ assert_includes available_locales, :en
77
+ assert_includes available_locales, :de
78
+ assert_includes available_locales, :uk
79
+ end
79
80
 
80
- test "fetching subtree of translations" do
81
- I18n::Backend::ActiveRecord::Translation.delete_all
82
- I18n.backend.store_translations(:en, foo: { bar: { fizz: 'buzz', spuz: 'zazz' }, baz: { fizz: 'buzz' } })
83
- assert_equal I18n.t(:foo), { bar: { fizz: 'buzz', spuz: 'zazz' }, baz: { fizz: 'buzz' } }
84
- end
81
+ test 'the default configuration has cleanup_with_destroy == false' do
82
+ refute I18n::Backend::ActiveRecord.config.cleanup_with_destroy
83
+ end
85
84
 
86
- test "build_translation_hash_by_key" do
87
- translation = I18n::Backend::ActiveRecord::Translation.new(value: 'translation', key: 'foo.bar.fizz.buzz')
88
- expected_hash = { 'bar' => { 'fizz' => { 'buzz' => 'translation' } } }
89
- assert_equal I18n.backend.send(:build_translation_hash_by_key, 'foo', translation), expected_hash
90
- end
85
+ test 'the configuration supports cleanup_with_destroy being set' do
86
+ I18n::Backend::ActiveRecord.configure do |config|
87
+ config.cleanup_with_destroy = true
88
+ end
91
89
 
92
- test "returning all keys via ." do
93
- expected_hash = {:foo => { :bar => 'bar', :baz => 'baz' }}
94
- assert_equal expected_hash, I18n.t('.')
95
- end
90
+ assert I18n::Backend::ActiveRecord.config.cleanup_with_destroy
91
+ end
96
92
 
97
- test "accessing keys with a trailing/leading period" do
98
- expected_hash = { :bar => 'bar', :baz => 'baz' }
99
- assert_equal expected_hash, I18n.t('foo')
100
- assert_equal expected_hash, I18n.t('.foo')
101
- assert_equal expected_hash, I18n.t('foo.')
102
- assert_equal expected_hash, I18n.t('.foo.')
103
- assert_equal expected_hash, I18n.t('.foo.')
104
- end
93
+ test 'fetching subtree of translations' do
94
+ store_translations(:en, foo: { bar: { fizz: 'buzz', spuz: 'zazz' }, baz: { fizz: 'buzz' } })
105
95
 
106
- test "returning all keys via . when there are no keys" do
107
- I18n.t('.') # Fixes test flakiness by loading available locales
108
- I18n::Backend::ActiveRecord::Translation.destroy_all
96
+ assert_equal I18n.t(:foo), { bar: { fizz: 'buzz', spuz: 'zazz' }, baz: { fizz: 'buzz' } }
97
+ end
109
98
 
110
- assert_equal "translation missing: en.no key", I18n.t('.')
111
- end
99
+ test 'build_translation_hash_by_key' do
100
+ translation = I18n::Backend::ActiveRecord::Translation.new(value: 'translation', key: 'foo.bar.fizz.buzz')
101
+ expected_hash = { 'bar' => { 'fizz' => { 'buzz' => 'translation' } } }
112
102
 
113
- test "intially unitinitialized" do
114
- refute I18n.backend.initialized?
115
- I18n.backend.init_translations
116
- assert I18n.backend.initialized?
117
- I18n.backend.reload!
118
- refute I18n.backend.initialized?
119
- I18n.backend.init_translations
120
- assert I18n.backend.initialized?
121
- end
103
+ assert_equal I18n.backend.send(:build_translation_hash_by_key, 'foo', translation), expected_hash
104
+ end
105
+
106
+ test 'returning all keys via .' do
107
+ expected_hash = { foo: { bar: 'bar', baz: 'baz' } }
108
+
109
+ assert_equal expected_hash, I18n.t('.')
110
+ end
111
+
112
+ test 'accessing keys with a trailing/leading period' do
113
+ expected_hash = { bar: 'bar', baz: 'baz' }
114
+
115
+ assert_equal expected_hash, I18n.t('foo')
116
+ assert_equal expected_hash, I18n.t('.foo')
117
+ assert_equal expected_hash, I18n.t('foo.')
118
+ assert_equal expected_hash, I18n.t('.foo.')
119
+ assert_equal expected_hash, I18n.t('.foo.')
120
+ end
121
+
122
+ test 'returning all keys via . when there are no keys' do
123
+ I18n.t('.') # Fixes test flakiness by loading available locales
124
+ I18n::Backend::ActiveRecord::Translation.destroy_all
125
+
126
+ assert_equal 'translation missing: en.no key', I18n.t('.')
127
+ end
128
+
129
+ test 'intially unitinitialized' do
130
+ refute I18n.backend.initialized?
131
+
132
+ I18n.backend.init_translations
133
+ assert I18n.backend.initialized?
134
+
135
+ I18n.backend.reload!
136
+ refute I18n.backend.initialized?
137
+
138
+ I18n.backend.init_translations
139
+ assert I18n.backend.initialized?
140
+ end
141
+
142
+ test 'translations returns all translations' do
143
+ expected_hash = { en: { foo: { bar: 'bar', baz: 'baz' } } }
144
+ I18n.backend.init_translations
122
145
 
123
- test "translations returns all translations" do
124
- expected_hash = { :en => { :foo => { :bar => 'bar', :baz => 'baz' } } }
125
- I18n.backend.init_translations
126
- assert_equal expected_hash, I18n.backend.send(:translations)
127
- assert I18n.backend.initialized?
146
+ assert_equal expected_hash, I18n.backend.send(:translations)
147
+ assert I18n.backend.initialized?
148
+ end
149
+
150
+ test 'translations initialized with do_init argument' do
151
+ expected_hash = { en: { foo: { bar: 'bar', baz: 'baz' } } }
152
+
153
+ refute I18n.backend.initialized?
154
+ assert_equal expected_hash, I18n.backend.send(:translations, do_init: true)
155
+ assert I18n.backend.initialized?
156
+ end
128
157
  end
129
158
 
130
- test "translations initialized with do_init argument" do
131
- expected_hash = { :en => { :foo => { :bar => 'bar', :baz => 'baz' } } }
132
- refute I18n.backend.initialized?
133
- assert_equal expected_hash, I18n.backend.send(:translations, { do_init: true })
134
- assert I18n.backend.initialized?
159
+ class WithCacheTest < WithoutCacheTest
160
+ def setup
161
+ super
162
+
163
+ I18n::Backend::ActiveRecord.config.cache_translations = true
164
+ end
135
165
  end
136
166
  end
data/test/api_test.rb CHANGED
@@ -1,8 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class I18nActiveRecordApiTest < I18n::TestCase
4
6
  def setup
5
7
  I18n.backend = I18n::Backend::ActiveRecord.new
8
+
6
9
  super
7
10
  end
8
11
 
@@ -23,7 +26,7 @@ class I18nActiveRecordApiTest < I18n::TestCase
23
26
  include I18n::Tests::Localization::Time
24
27
  include I18n::Tests::Localization::Procs if can_store_procs?
25
28
 
26
- test "make sure we use an ActiveRecord backend" do
29
+ test 'make sure we use an ActiveRecord backend' do
27
30
  assert_equal I18n::Backend::ActiveRecord, I18n.backend.class
28
31
  end
29
32
  end
data/test/missing_test.rb CHANGED
@@ -1,70 +1,107 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
5
  class I18nActiveRecordMissingTest < I18n::TestCase
4
- class Backend < I18n::Backend::ActiveRecord
6
+ class BackendWithMissing < I18n::Backend::ActiveRecord
5
7
  include I18n::Backend::ActiveRecord::Missing
6
8
  end
7
9
 
8
10
  def setup
9
- I18n.backend.store_translations(:en, :bar => 'Bar', :i18n => { :plural => { :keys => [:zero, :one, :other] } })
10
- I18n.backend = I18n::Backend::Chain.new(Backend.new, I18n.backend)
11
- I18n::Backend::ActiveRecord::Translation.delete_all
12
- end
11
+ super
12
+
13
+ I18n::Backend::ActiveRecord::Translation.destroy_all
14
+ I18n.backend = BackendWithMissing.new
13
15
 
14
- test "can persist interpolations" do
15
- translation = I18n::Backend::ActiveRecord::Translation.new(:key => 'foo', :value => 'bar', :locale => :en)
16
- translation.interpolations = %w(count name)
17
- translation.save
18
- assert translation.valid?
16
+ store_translations(:en, bar: 'Bar', i18n: { plural: { keys: %i[zero one other] } })
19
17
  end
20
18
 
21
- test "lookup persists the key" do
22
- I18n.t('foo.bar.baz')
19
+ def teardown
20
+ I18n::Backend::ActiveRecord.instance_variable_set :@config, I18n::Backend::ActiveRecord::Configuration.new
23
21
 
24
- assert_equal 1, I18n::Backend::ActiveRecord::Translation.count
25
- assert I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo.bar.baz')
22
+ super
26
23
  end
27
24
 
28
- test "lookup does not persist the key twice" do
29
- 2.times { I18n.t('foo.bar.baz') }
30
- assert_equal 1, I18n::Backend::ActiveRecord::Translation.count
31
- assert I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo.bar.baz')
32
- end
25
+ class WithoutCacheTest < I18nActiveRecordMissingTest
26
+ def setup
27
+ super
33
28
 
34
- test "lookup persists interpolation keys when looked up directly" do
35
- I18n.t('foo.bar.baz', :cow => "lucy" ) # creates stub translation.
36
- translation_stub = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo.bar.baz').first
37
- assert translation_stub.interpolates?(:cow)
38
- end
29
+ I18n::Backend::ActiveRecord.config.cache_translations = false
30
+ end
39
31
 
40
- test "creates one stub per pluralization" do
41
- I18n.t('foo', :count => 999)
42
- translations = I18n::Backend::ActiveRecord::Translation.locale(:en).where key: %w{ foo.zero foo.one foo.other }
43
- assert_equal 3, translations.length
44
- end
32
+ test 'can persist interpolations' do
33
+ translation = I18n::Backend::ActiveRecord::Translation.new(key: 'foo', value: 'bar', locale: :en)
34
+ translation.interpolations = %w[count name]
35
+ translation.save
45
36
 
46
- test "creates no stub for base key in pluralization" do
47
- I18n.t('foo', :count => 999)
48
- assert_equal 3, I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo").count
49
- assert !I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key("foo")
50
- end
37
+ assert translation.valid?
38
+ end
51
39
 
52
- test "creates a stub when a custom separator is used" do
53
- I18n.t('foo|baz', :separator => '|')
54
- I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo.baz").first.update(:value => 'baz!')
55
- assert_equal 'baz!', I18n.t('foo|baz', :separator => '|')
56
- end
40
+ test 'lookup persists the key' do
41
+ I18n.t('foo.bar.baz')
42
+
43
+ assert_equal 3, I18n::Backend::ActiveRecord::Translation.count
44
+ assert I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo.bar.baz')
45
+ end
46
+
47
+ test 'lookup does not persist the key twice' do
48
+ 2.times { I18n.t('foo.bar.baz') }
49
+
50
+ assert_equal 3, I18n::Backend::ActiveRecord::Translation.count
51
+ assert I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo.bar.baz')
52
+ end
53
+
54
+ test 'lookup persists interpolation keys when looked up directly' do
55
+ I18n.t('foo.bar.baz', cow: 'lucy') # creates stub translation.
56
+ translation_stub = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo.bar.baz').first
57
57
 
58
- test "creates a stub per pluralization when a custom separator is used" do
59
- I18n.t('foo|bar', :count => 999, :separator => '|')
60
- translations = I18n::Backend::ActiveRecord::Translation.locale(:en).where key: %w{ foo.bar.zero foo.bar.one foo.bar.other }
61
- assert_equal 3, translations.length
58
+ assert translation_stub.interpolates?(:cow)
59
+ end
60
+
61
+ test 'creates one stub per pluralization' do
62
+ I18n.t('foo', count: 999)
63
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).where(key: %w[foo.zero foo.one foo.other])
64
+
65
+ assert_equal 3, translations.length
66
+ end
67
+
68
+ test 'creates no stub for base key in pluralization' do
69
+ I18n.t('foo', count: 999)
70
+
71
+ assert_equal 3, I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').count
72
+ assert !I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo')
73
+ end
74
+
75
+ test 'creates a stub when a custom separator is used' do
76
+ I18n.t('foo|baz', separator: '|')
77
+ I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo.baz').first.update(value: 'baz!')
78
+
79
+ assert_equal 'baz!', I18n.t('foo|baz', separator: '|')
80
+ end
81
+
82
+ test 'creates a stub per pluralization when a custom separator is used' do
83
+ I18n.t('foo|bar', count: 999, separator: '|')
84
+ translations = I18n::Backend::ActiveRecord::Translation
85
+ .locale(:en)
86
+ .where(key: %w[foo.bar.zero foo.bar.one foo.bar.other])
87
+
88
+ assert_equal 3, translations.length
89
+ end
90
+
91
+ test 'creates a stub when a custom separator is used and the key contains the flatten separator(a dot character)' do
92
+ key = 'foo|baz.zab'
93
+ I18n.t(key, separator: '|')
94
+ I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo.baz\001zab").first.update(value: 'baz!')
95
+
96
+ assert_equal 'baz!', I18n.t(key, separator: '|')
97
+ end
62
98
  end
63
99
 
64
- test "creates a stub when a custom separator is used and the key contains the flatten separator (a dot character)" do
65
- key = 'foo|baz.zab'
66
- I18n.t(key, :separator => '|')
67
- I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo.baz\001zab").first.update(:value => 'baz!')
68
- assert_equal 'baz!', I18n.t(key, :separator => '|')
100
+ class WithCacheTest < WithoutCacheTest
101
+ def setup
102
+ super
103
+
104
+ I18n::Backend::ActiveRecord.config.cache_translations = true
105
+ end
69
106
  end
70
107
  end
data/test/test_helper.rb CHANGED
@@ -1,8 +1,8 @@
1
- $KCODE = 'u' if RUBY_VERSION <= '1.9'
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/setup'
4
4
  require 'minitest/autorun'
5
- require 'mocha/setup'
5
+ require 'mocha/minitest'
6
6
  require 'test_declarative'
7
7
 
8
8
  require 'i18n/active_record'
@@ -15,67 +15,79 @@ rescue LoadError => e
15
15
  puts "can't use ActiveRecord backend because: #{e.message}"
16
16
  rescue ::ActiveRecord::ConnectionNotEstablished
17
17
  require 'i18n/backend/active_record'
18
+
18
19
  case ENV['DB']
19
20
  when 'postgres'
20
- ::ActiveRecord::Base.establish_connection adapter: 'postgresql', database: 'i18n_unittest', username: ENV['PG_USER'] || 'i18n', password: '', host: 'localhost'
21
+ ::ActiveRecord::Base.establish_connection(
22
+ adapter: 'postgresql',
23
+ database: 'i18n_unittest',
24
+ username: ENV['PG_USER'] || 'postgres',
25
+ password: ENV['PG_PASSWORD'] || 'postgres',
26
+ host: 'localhost'
27
+ )
21
28
  when 'mysql'
22
- ::ActiveRecord::Base.establish_connection adapter: 'mysql2', database: 'i18n_unittest', username: 'root', password: '', host: 'localhost'
29
+ ::ActiveRecord::Base.establish_connection(
30
+ adapter: 'mysql2',
31
+ database: 'i18n_unittest',
32
+ username: ENV['MYSQL_USER'] || 'root',
33
+ password: ENV['MYSQL_PASSWORD'] || '',
34
+ host: '127.0.0.1'
35
+ )
23
36
  else
24
37
  ::ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
25
38
  end
39
+
26
40
  ::ActiveRecord::Migration.verbose = false
27
- ::ActiveRecord::Schema.define(:version => 1) do
28
- create_table :translations, :force => true do |t|
41
+ ::ActiveRecord::Schema.define(version: 1) do
42
+ create_table :translations, force: true do |t|
29
43
  t.string :locale
30
44
  t.string :key
31
45
  t.text :value
32
46
  t.text :interpolations
33
- t.boolean :is_proc, :default => false
47
+ t.boolean :is_proc, default: false
34
48
  end
35
- add_index :translations, [:locale, :key], :unique => true
49
+ add_index :translations, %i[locale key], unique: true
36
50
  end
37
51
  end
38
52
 
39
53
  TEST_CASE = defined?(Minitest::Test) ? Minitest::Test : MiniTest::Unit::TestCase
40
54
 
41
- class TEST_CASE
42
- alias :assert_raise :assert_raises
43
- alias :assert_not_equal :refute_equal
55
+ class TEST_CASE # rubocop:disable Naming/ClassAndModuleCamelCase
56
+ alias assert_raise assert_raises
57
+ alias assert_not_equal refute_equal
44
58
 
45
- def assert_nothing_raised(*args)
59
+ def assert_nothing_raised(*_args)
46
60
  yield
47
61
  end
48
62
  end
49
63
 
50
- class I18n::TestCase < TEST_CASE
51
- def setup
52
- I18n.enforce_available_locales = false
53
- I18n.available_locales = []
54
- I18n.locale = :en
55
- I18n.default_locale = :en
56
- I18n.load_path = []
57
- super
58
- end
59
-
60
- def teardown
61
- I18n.enforce_available_locales = false
62
- I18n.available_locales = []
63
- I18n.locale = :en
64
- I18n.default_locale = :en
65
- I18n.load_path = []
66
- I18n.backend = nil
67
- super
68
- end
64
+ module I18n
65
+ class TestCase < TEST_CASE
66
+ def setup
67
+ I18n.enforce_available_locales = false
68
+ I18n.available_locales = []
69
+ I18n.locale = :en
70
+ I18n.default_locale = :en
71
+ I18n.load_path = []
72
+ super
73
+ end
69
74
 
70
- def translations
71
- I18n.backend.instance_variable_get(:@translations)
72
- end
75
+ def teardown
76
+ I18n.enforce_available_locales = false
77
+ I18n.available_locales = []
78
+ I18n.locale = :en
79
+ I18n.default_locale = :en
80
+ I18n.load_path = []
81
+ I18n.backend = nil
82
+ super
83
+ end
73
84
 
74
- def store_translations(locale, data)
75
- I18n.backend.store_translations(locale, data)
76
- end
85
+ def store_translations(locale, data)
86
+ I18n.backend.store_translations(locale, data)
87
+ end
77
88
 
78
- def locales_dir
79
- File.dirname(__FILE__) + '/test_data/locales'
89
+ def locales_dir
90
+ "#{File.dirname(__FILE__)}/test_data/locales"
91
+ end
80
92
  end
81
93
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: i18n-active_record
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sven Fuchs
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-08-24 00:00:00.000000000 Z
11
+ date: 2021-10-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.5.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: appraisal
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -38,6 +52,76 @@ dependencies:
38
52
  - - ">="
39
53
  - !ruby/object:Gem::Version
40
54
  version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: minitest
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: mocha
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rake
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: test_declarative
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - ">="
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - ">="
123
+ - !ruby/object:Gem::Version
124
+ version: '0'
41
125
  description: I18n ActiveRecord backend. Allows to store translations in a database
42
126
  using ActiveRecord, e.g. for providing a web-interface for managing translations.
43
127
  email: svenfuchs@artweb-design.de
@@ -82,7 +166,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
82
166
  - !ruby/object:Gem::Version
83
167
  version: '0'
84
168
  requirements: []
85
- rubygems_version: 3.1.4
169
+ rubygems_version: 3.2.29
86
170
  signing_key:
87
171
  specification_version: 4
88
172
  summary: I18n ActiveRecord backend