serial_translator 1.1.0 → 2.0.3

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
- SHA1:
3
- metadata.gz: 978f519c27807266eafae6bca4cb6b5ce25e4873
4
- data.tar.gz: 0bc4da881ec6461d987357142d9e196dec5bab4f
2
+ SHA256:
3
+ metadata.gz: e67a98e574e71655f1d1c1de15b35356db3bd0501e06c464d207591a2d8a4da6
4
+ data.tar.gz: c2ab2da70fdb53ab500912f5ec061e6a504765735a5a518be73869b0839eb2e4
5
5
  SHA512:
6
- metadata.gz: f90077f42eb3affea9fb9cd1adbcd672236da372098f555edaf33d34785fdc1f28eec33eafd8ae4c0088603ee2b0a663cf796613d0092110fbb929aa9a190a1f
7
- data.tar.gz: 97153aa7d77d5e22522afcbfb4e422ae113c923b99f44f5eac5ad82ea312f1eb137dfedc26067eb16dafa51d413c6bde64997a12310a755620397dd547aa940c
6
+ metadata.gz: c98bb5a850f094b31691f12165095187db6e5df31cc2a46624df1059136c9b58cd8fa3b9115b34d37f336d3ee06c80f90a5fe1b9067abe036029f65236f19458
7
+ data.tar.gz: a33d2d1793c60dfc441f4c7ced0397cc09bcddfba6904fedc49d63c2e74034d3adc260c9662eea9905c2f5a9e06ccf085395ef760080f711281a8be2466752d3
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ errors.lst
data/.tool-versions ADDED
@@ -0,0 +1 @@
1
+ ruby 3.0.0
data/.travis.yml CHANGED
@@ -1,11 +1,12 @@
1
- rvm:
2
- - 2.3.2
1
+ before_install:
2
+ - gem update --system
3
+ - gem update bundler
3
4
 
4
- script: "bundle exec rake"
5
+ rvm:
6
+ - 2.7
7
+ - 3.0
5
8
 
6
9
  notifications:
7
10
  disabled: false
8
11
  recipients:
9
12
  - developers@betterplace.org
10
-
11
- sudo: false
data/.utilsrc ADDED
@@ -0,0 +1,26 @@
1
+ # vim: set ft=ruby:
2
+
3
+ search do
4
+ prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|pkg)\z/
5
+ skip_files /(\A\.|\.sw[pon]\z|\.(log|fnm|jpg|jpeg|png|pdf|svg)\z|tags|~\z)/i
6
+ end
7
+
8
+ discover do
9
+ prune_dirs /\A(\.svn|\.git|CVS|tmp|tags|coverage|pkg)\z/
10
+ skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
11
+ binary false
12
+ end
13
+
14
+ strip_spaces do
15
+ prune_dirs /\A(\..*|CVS|pkg)\z/
16
+ skip_files /(\A\.|\.sw[pon]\z|\.log\z|~\z)/
17
+ end
18
+
19
+ probe do
20
+ test_framework :rspec
21
+ #include_dirs 'features'
22
+ end
23
+
24
+ ssh_tunnel do
25
+ terminal_multiplexer :tmux
26
+ end
data/README.md CHANGED
@@ -6,6 +6,10 @@
6
6
 
7
7
  Translate ActiveRecord object attributes without the use of additional models.
8
8
 
9
+ ## Changes from 1.* to 2.*
10
+
11
+ `serial_translator` will now store all translations in JSON format per default rather than in YAML. However, it is still able to read YAML serialized translations and will convert them in the background.
12
+
9
13
  ## Installation
10
14
 
11
15
  Add it to your Gemfile:
@@ -1,8 +1,11 @@
1
1
  require 'active_support'
2
2
  require 'active_model'
3
+ require 'active_record'
3
4
 
4
5
  require 'serial_translator/serial_translator_length_validator'
5
6
  require 'serial_translator/serial_translator_presence_validator'
7
+ require 'serial_translator/translation_type'
8
+ require 'serial_translator/version'
6
9
 
7
10
  module SerialTranslator
8
11
  extend ActiveSupport::Concern
@@ -11,48 +14,54 @@ module SerialTranslator
11
14
  attr_writer :current_translation_locale, :translation_fallback
12
15
  end
13
16
 
17
+ class InvalidLocaleError < StandardError
18
+ end
19
+
14
20
  module ClassMethods
15
21
  attr_reader :serial_translator_attributes
16
22
 
17
23
  def serial_translator_for(*attributes)
18
24
  @serial_translator_attributes = attributes
19
25
 
20
- attributes.each do |attribute|
21
- serialize :"#{attribute}_translations", Hash
26
+ attributes.each do |attr_name|
27
+ attribute :"#{attr_name}_translations", SerialTranslator::TranslationType.new
22
28
 
23
29
  # Define the normal getter, that respects the
24
30
  # current translation locale
25
- define_method attribute do |locale = current_translation_locale|
26
- translations = translations_for(attribute)
31
+ define_method attr_name do |locale = current_translation_locale|
32
+ translations = translations_for(attr_name)
27
33
  result = translations[locale] if translations[locale].present?
28
34
  result ||= translations.values.detect(&:present?) if translation_fallback?
29
35
  result
30
36
  end
31
37
 
32
- define_method :"#{attribute}?" do |locale = current_translation_locale|
33
- __send__(attribute.to_sym, locale).present?
38
+ define_method :"#{attr_name}?" do |locale = current_translation_locale|
39
+ __send__(attr_name.to_sym, locale).present?
34
40
  end
35
41
 
36
42
  # Define the normal setter, that respects the
37
43
  # current translation locale
38
- define_method "#{attribute}=" do |value|
39
- __send__(:"#{attribute}_translations_will_change!")
40
- translations = translations_for(attribute)
44
+ define_method "#{attr_name}=" do |value|
45
+ unless I18n.available_locales.include?(current_translation_locale)
46
+ raise InvalidLocaleError, "current_translation_locale #{current_translation_locale.inspect} is not a member of I18n.available_locales: #{I18n.available_locales.inspect}"
47
+ end
48
+ __send__(:"#{attr_name}_translations_will_change!")
49
+ translations = translations_for(attr_name)
41
50
  if value.present?
42
51
  translations[current_translation_locale] = value
43
52
  else
44
53
  translations.delete(current_translation_locale)
45
54
  end
46
- __send__(:"#{attribute}_translations=", translations)
55
+ __send__(:"#{attr_name}_translations=", translations)
47
56
  end
48
57
 
49
58
  # Define getters for each specific available locale
50
59
  I18n.available_locales.each do |available_locale|
51
- define_method "#{attribute}_#{available_locale.to_s.underscore}" do
60
+ define_method "#{attr_name}_#{available_locale.to_s.underscore}" do
52
61
  begin
53
62
  old_locale = I18n.locale
54
63
  I18n.locale = available_locale
55
- __send__(attribute)
64
+ __send__(attr_name)
56
65
  ensure
57
66
  I18n.locale = old_locale
58
67
  end
@@ -61,11 +70,11 @@ module SerialTranslator
61
70
 
62
71
  # Define setters for each specific available locale
63
72
  I18n.available_locales.each do |available_locale|
64
- define_method "#{attribute}_#{available_locale.to_s.underscore}=" do |value|
73
+ define_method "#{attr_name}_#{available_locale.to_s.underscore}=" do |value|
65
74
  begin
66
75
  old_locale = I18n.locale
67
76
  I18n.locale = available_locale
68
- __send__(:"#{attribute}=", value)
77
+ __send__(:"#{attr_name}=", value)
69
78
  ensure
70
79
  I18n.locale = old_locale
71
80
  end
@@ -29,7 +29,7 @@ module SerialTranslator
29
29
 
30
30
  default_message = options[MESSAGES[key]]
31
31
  error_options[:message] ||= default_message if default_message
32
- record.errors.add(attribute, MESSAGES[key], error_options)
32
+ record.errors.add(attribute, MESSAGES[key], **error_options)
33
33
  end
34
34
  end
35
35
 
@@ -3,9 +3,13 @@ module SerialTranslator
3
3
  def validate_each(record, attribute, _value)
4
4
  translations = record.__send__("#{attribute}_translations") || {}
5
5
  return if translations.values.any?(&:present?)
6
- record.errors.add_on_blank(attribute, options)
6
+ if record.send(attribute).blank?
7
+ record.errors.add(attribute, :blank, **options)
8
+ end
7
9
  end
8
10
 
9
- def kind; :presence end
11
+ def kind
12
+ :presence
13
+ end
10
14
  end
11
15
  end
@@ -0,0 +1,23 @@
1
+ class SerialTranslator::TranslationType < ActiveRecord::Type::String
2
+ def cast(value)
3
+ case value
4
+ when nil
5
+ {}
6
+ when Hash
7
+ value
8
+ when /\A---/
9
+ YAML.load(value)
10
+ else
11
+ JSON.parse(value).symbolize_keys
12
+ end
13
+ end
14
+
15
+ def serialize(value)
16
+ case value
17
+ when String
18
+ super
19
+ else
20
+ JSON(value)
21
+ end
22
+ end
23
+ end
@@ -1,3 +1,3 @@
1
1
  module SerialTranslator
2
- VERSION = "1.1.0"
2
+ VERSION = "2.0.3"
3
3
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'serial_translator/version'
@@ -18,11 +17,14 @@ Gem::Specification.new do |spec|
18
17
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
18
  spec.require_paths = ["lib"]
20
19
 
21
- spec.add_dependency 'activemodel', '>= 4.0.0'
20
+ spec.add_dependency 'activemodel', '>= 5'
21
+ spec.add_dependency 'activerecord', '>= 5'
22
22
 
23
- spec.add_development_dependency 'bundler', '~> 1.3'
23
+ spec.add_development_dependency 'bundler'
24
24
  spec.add_development_dependency 'rake'
25
25
  spec.add_development_dependency 'rspec'
26
26
  spec.add_development_dependency 'rspec-collection_matchers'
27
+ spec.add_development_dependency 'json', '~>2'
27
28
  spec.add_development_dependency 'simplecov'
29
+ spec.add_development_dependency 'sqlite3'
28
30
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SerialTranslator::SerialTranslatorLengthValidator do
4
- let(:example) { FakeObject.new }
4
+ let(:example) { Fake.new }
5
5
 
6
6
  describe 'validation' do
7
7
  it 'validates min length correctly' do
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SerialTranslator::SerialTranslatorPresenceValidator do
4
- let(:example) { FakeObject.new }
4
+ let(:example) { Fake.new }
5
5
 
6
6
  describe 'validation' do
7
7
  it 'validates presence correctly if attribute is nil' do
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ describe SerialTranslator::TranslationType do
4
+ let(:type) { SerialTranslator::TranslationType.new }
5
+
6
+ describe '#cast' do
7
+ it 'works for JSON' do
8
+ expect(type.cast('{"foo":"bar"}')).to eq(foo: 'bar')
9
+ end
10
+
11
+ it 'works for YAML' do
12
+ expect(type.cast("---\nfoo: bar")).to eq('foo' => 'bar')
13
+ end
14
+
15
+ it 'does nothing if already a Hash' do
16
+ expect(type.cast({foo: :bar})).to eq(foo: :bar)
17
+ end
18
+
19
+ it 'defaults to empty hash' do
20
+ expect(type.cast(nil)).to eq({})
21
+ end
22
+ end
23
+
24
+ describe '#serialize' do
25
+ it 'converts to JSON' do
26
+ expect(type.serialize({foo: :bar})).to eq('{"foo":"bar"}')
27
+ end
28
+
29
+ it 'leaves strings alone (to avoid double serialization)' do
30
+ expect(type.serialize('foo')).to eq 'foo'
31
+ end
32
+ end
33
+ end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
3
  describe SerialTranslator do
4
- let(:object) { FakeObject.new }
4
+ let(:object) { Fake.new }
5
5
 
6
6
  describe 'getting a translated value' do
7
7
  it 'returns the translated value in the requested locale' do
@@ -48,6 +48,12 @@ describe SerialTranslator do
48
48
  expect(object.title_translations).to eq({ de: 'Deutsch' })
49
49
  end
50
50
 
51
+ it 'raises an error if current translation is not an I18n locale' do
52
+ object.current_translation_locale = :foobar
53
+ expect { object.title = 'Deutsch' }.to raise_error(SerialTranslator::InvalidLocaleError)
54
+ expect(object.title_translations).to eq({})
55
+ end
56
+
51
57
  it 'nil removes the value for the current text locale' do
52
58
  object.title_translations = { de: 'Deutsch' }
53
59
  object.current_translation_locale = :de
@@ -136,4 +142,18 @@ describe SerialTranslator do
136
142
  expect(object).to_not be_translated_into :yml
137
143
  end
138
144
  end
145
+
146
+ context 'use active record methods' do
147
+ it 'works with where and LIKE' do
148
+ expect {
149
+ Fake.where('title_translations LIKE ?', '%foobar').count
150
+ }.not_to raise_error
151
+ end
152
+
153
+ it 'works with where and Hash syntax' do
154
+ expect {
155
+ Fake.where(title_translations: 'foobar').count
156
+ }.not_to raise_error
157
+ end
158
+ end
139
159
  end
data/spec/spec_helper.rb CHANGED
@@ -7,6 +7,6 @@ end
7
7
  SimpleCov.start 'gem'
8
8
 
9
9
  require 'serial_translator'
10
- require 'active_model'
11
- require 'support/fake_object'
12
10
  require 'rspec/collection_matchers'
11
+ require 'support/fake_env'
12
+ require 'active_record'
@@ -1,27 +1,25 @@
1
- # This class is only used for testing purposes.
2
- class FakeObject
3
- include ActiveModel::Validations
4
- include SerialTranslator
5
-
6
- def self.serialize(*); end
1
+ ActiveRecord::Base.establish_connection adapter: 'sqlite3', database: ':memory:'
2
+
3
+ ActiveRecord::Schema.define do
4
+ self.verbose = false
5
+
6
+ create_table :fakes, force: true do |t|
7
+ t.text :description_translations
8
+ t.text :title_translations
9
+ t.text :subtitle_translations
10
+ t.text :summary_translations
11
+ t.text :credits_translations
12
+ t.text :imprint_translations
13
+ end
14
+ end
7
15
 
8
- def self.before_save(*); end
16
+ class Fake < ActiveRecord::Base
17
+ include SerialTranslator
9
18
 
10
19
  # Has to be set in this context to test it correctly
11
20
  I18n.available_locales = [:en, :de, :'en-GB']
12
21
 
13
- TRANSLATED_ATTRIBUTES = %w(description title subtitle summary credits imprint)
14
-
15
- serial_translator_for(*TRANSLATED_ATTRIBUTES)
16
-
17
- TRANSLATED_ATTRIBUTES.map {|ta| "#{ta}_translations" }.each do |hash_name|
18
- attr_accessor hash_name
19
- define_method("#{hash_name}_will_change!") { changes << hash_name.to_sym }
20
- end
21
-
22
- def changes
23
- @changes ||= []
24
- end
22
+ serial_translator_for(*%w(description title subtitle summary credits imprint))
25
23
 
26
24
  validates :description, serial_translator_presence: true
27
25
  validates :title, serial_translator_length: { within: 5..25 }
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: serial_translator
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.0
4
+ version: 2.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - betterplace development team
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-12-08 00:00:00.000000000 Z
11
+ date: 2021-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
@@ -16,28 +16,42 @@ dependencies:
16
16
  requirements:
17
17
  - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: 4.0.0
19
+ version: '5'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: 4.0.0
26
+ version: '5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activerecord
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '5'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '5'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
30
44
  requirements:
31
- - - "~>"
45
+ - - ">="
32
46
  - !ruby/object:Gem::Version
33
- version: '1.3'
47
+ version: '0'
34
48
  type: :development
35
49
  prerelease: false
36
50
  version_requirements: !ruby/object:Gem::Requirement
37
51
  requirements:
38
- - - "~>"
52
+ - - ">="
39
53
  - !ruby/object:Gem::Version
40
- version: '1.3'
54
+ version: '0'
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rake
43
57
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +94,20 @@ dependencies:
80
94
  - - ">="
81
95
  - !ruby/object:Gem::Version
82
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: json
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: '2'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: '2'
83
111
  - !ruby/object:Gem::Dependency
84
112
  name: simplecov
85
113
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +122,20 @@ dependencies:
94
122
  - - ">="
95
123
  - !ruby/object:Gem::Version
96
124
  version: '0'
125
+ - !ruby/object:Gem::Dependency
126
+ name: sqlite3
127
+ requirement: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ type: :development
133
+ prerelease: false
134
+ version_requirements: !ruby/object:Gem::Requirement
135
+ requirements:
136
+ - - ">="
137
+ - !ruby/object:Gem::Version
138
+ version: '0'
97
139
  description: Translate attribute values without additional models
98
140
  email:
99
141
  - developers@betterplace.org
@@ -103,7 +145,9 @@ extra_rdoc_files: []
103
145
  files:
104
146
  - ".gitignore"
105
147
  - ".rspec"
148
+ - ".tool-versions"
106
149
  - ".travis.yml"
150
+ - ".utilsrc"
107
151
  - Gemfile
108
152
  - LICENSE.txt
109
153
  - README.md
@@ -111,18 +155,20 @@ files:
111
155
  - lib/serial_translator.rb
112
156
  - lib/serial_translator/serial_translator_length_validator.rb
113
157
  - lib/serial_translator/serial_translator_presence_validator.rb
158
+ - lib/serial_translator/translation_type.rb
114
159
  - lib/serial_translator/version.rb
115
160
  - serial_translator.gemspec
116
161
  - spec/lib/serial_translator/serial_translator_length_validator_spec.rb
117
162
  - spec/lib/serial_translator/serial_translator_presence_validator_spec.rb
163
+ - spec/lib/serial_translator/translation_type_spec.rb
118
164
  - spec/lib/serial_translator_spec.rb
119
165
  - spec/spec_helper.rb
120
- - spec/support/fake_object.rb
166
+ - spec/support/fake_env.rb
121
167
  homepage: http://www.betterplace.org
122
168
  licenses:
123
169
  - WTFPL
124
170
  metadata: {}
125
- post_install_message:
171
+ post_install_message:
126
172
  rdoc_options: []
127
173
  require_paths:
128
174
  - lib
@@ -137,14 +183,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
137
183
  - !ruby/object:Gem::Version
138
184
  version: '0'
139
185
  requirements: []
140
- rubyforge_project:
141
- rubygems_version: 2.6.8
142
- signing_key:
186
+ rubygems_version: 3.2.3
187
+ signing_key:
143
188
  specification_version: 4
144
189
  summary: Translate attribute values without additional models
145
190
  test_files:
146
191
  - spec/lib/serial_translator/serial_translator_length_validator_spec.rb
147
192
  - spec/lib/serial_translator/serial_translator_presence_validator_spec.rb
193
+ - spec/lib/serial_translator/translation_type_spec.rb
148
194
  - spec/lib/serial_translator_spec.rb
149
195
  - spec/spec_helper.rb
150
- - spec/support/fake_object.rb
196
+ - spec/support/fake_env.rb