embedded_localization 1.3.1 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -0
- data/Gemfile +14 -3
- data/README.md +133 -5
- data/Rakefile +4 -14
- data/embedded_localization.gemspec +16 -13
- data/lib/embedded_localization/active_record/act_macro.rb +29 -67
- data/lib/embedded_localization/active_record/class_methods.rb +14 -0
- data/lib/embedded_localization/active_record/instance_methods.rb +52 -32
- data/lib/embedded_localization/storage/hstore.rb +61 -0
- data/lib/embedded_localization/storage/json.rb +25 -0
- data/lib/embedded_localization/version.rb +1 -1
- data/lib/embedded_localization.rb +6 -3
- metadata +11 -28
- data/.github/dependabot.yml +0 -8
- data/.github/workflows/codeql-analysis.yml +0 -72
- data/.github/workflows/ruby.yml +0 -64
- data/.gitignore +0 -7
- data/.rspec +0 -1
- data/lib/extensions/hash.rb +0 -7
- data/spec/embedded_localization/native_column_spec.rb +0 -191
- data/spec/embedded_localization/simple_model_spec.rb +0 -190
- data/spec/models.rb +0 -7
- data/spec/schema.rb +0 -18
- data/spec/spec.opts +0 -2
- data/spec/spec_helper.rb +0 -36
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
module EmbeddedLocalization
|
|
2
|
+
module Storage
|
|
3
|
+
# ActiveRecord attribute type for a PostgreSQL hstore `i18n` column.
|
|
4
|
+
#
|
|
5
|
+
# hstore is a flat String => String map, so each translation is stored under the key "<locale>.<attribute>",
|
|
6
|
+
# e.g. "de.name" => "Science-Fiction". In Ruby the gem works with the nested Hash {de: {name: "Science-Fiction"}}.
|
|
7
|
+
# Reading and writing the hstore text format is delegated to ActiveRecord's own hstore type.
|
|
8
|
+
class Hstore < ::ActiveRecord::Type::Value
|
|
9
|
+
include ::ActiveModel::Type::Helpers::Mutable
|
|
10
|
+
|
|
11
|
+
SEPARATOR = '.'.freeze
|
|
12
|
+
|
|
13
|
+
def type
|
|
14
|
+
:hstore
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def deserialize(value)
|
|
18
|
+
nest(hstore.deserialize(value))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def serialize(value)
|
|
22
|
+
hstore.serialize(flatten(value))
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def changed_in_place?(raw_old_value, new_value)
|
|
26
|
+
deserialize(raw_old_value) != new_value
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
private
|
|
30
|
+
|
|
31
|
+
# ActiveRecord registers the hstore type when the PostgreSQL adapter is loaded, i.e. when the connection is
|
|
32
|
+
# established; it is looked up on first use, so a model can be defined before the connection exists.
|
|
33
|
+
def hstore
|
|
34
|
+
@hstore ||= ::ActiveRecord::Type.lookup(:hstore, adapter: :postgresql)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# {de: {name: "x"}} => {"de.name" => "x"}
|
|
38
|
+
def flatten(translations)
|
|
39
|
+
return translations unless translations.is_a?(::Hash)
|
|
40
|
+
|
|
41
|
+
translations.each_with_object({}) do |(locale, attributes), flat|
|
|
42
|
+
next unless attributes.is_a?(::Hash)
|
|
43
|
+
|
|
44
|
+
attributes.each { |attr_name, value| flat["#{locale}#{SEPARATOR}#{attr_name}"] = value }
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# {"de.name" => "x"} => {de: {name: "x"}} ; keys without a separator are ignored
|
|
49
|
+
def nest(flat)
|
|
50
|
+
return flat unless flat.is_a?(::Hash)
|
|
51
|
+
|
|
52
|
+
flat.each_with_object({}) do |(key, value), translations|
|
|
53
|
+
locale, attr_name = key.split(SEPARATOR, 2)
|
|
54
|
+
next unless attr_name
|
|
55
|
+
|
|
56
|
+
(translations[locale.to_sym] ||= {})[attr_name.to_sym] = value
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
module EmbeddedLocalization
|
|
2
|
+
module Storage
|
|
3
|
+
# ActiveRecord attribute type for a json or jsonb `i18n` column.
|
|
4
|
+
#
|
|
5
|
+
# The column holds {"en" => {"name" => "..."}, "de" => {...}}; in Ruby the gem works with Symbol keys on both
|
|
6
|
+
# levels, so this type converts the keys whenever a value comes from the database. Assignment goes through the
|
|
7
|
+
# same conversion: ActiveRecord::Type::Json includes ActiveModel::Type::Helpers::Mutable, whose cast(value) is
|
|
8
|
+
# deserialize(serialize(value)).
|
|
9
|
+
class Json < ::ActiveRecord::Type::Json
|
|
10
|
+
def deserialize(value)
|
|
11
|
+
symbolize_keys(super)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
private
|
|
15
|
+
|
|
16
|
+
def symbolize_keys(translations)
|
|
17
|
+
return translations unless translations.is_a?(::Hash)
|
|
18
|
+
|
|
19
|
+
translations.each_with_object({}) do |(locale, attributes), result|
|
|
20
|
+
result[locale.to_sym] = attributes.is_a?(::Hash) ? attributes.transform_keys(&:to_sym) : attributes
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
require "active_record"
|
|
2
2
|
require "embedded_localization/version"
|
|
3
|
-
require 'extensions/hash'
|
|
4
3
|
|
|
5
4
|
module EmbeddedLocalization
|
|
6
5
|
autoload :ActiveRecord, 'embedded_localization/active_record'
|
|
6
|
+
|
|
7
|
+
# ActiveRecord attribute types for the `i18n` column when it is not a YAML text column
|
|
8
|
+
module Storage
|
|
9
|
+
autoload :Json, 'embedded_localization/storage/json'
|
|
10
|
+
autoload :Hstore, 'embedded_localization/storage/hstore'
|
|
11
|
+
end
|
|
7
12
|
end
|
|
8
13
|
|
|
9
|
-
# we're assuming for now only to be used with ActiveRecord 3, which is auto-required above
|
|
10
14
|
ActiveRecord::Base.extend(EmbeddedLocalization::ActiveRecord::ActMacro)
|
|
11
15
|
|
|
12
16
|
#-
|
|
@@ -30,4 +34,3 @@ ActiveRecord::Base.extend(EmbeddedLocalization::ActiveRecord::ActMacro)
|
|
|
30
34
|
|
|
31
35
|
# not as general:
|
|
32
36
|
# I18n::Backend::Simple.send(:include, I18n::Backend::Fallbacks)
|
|
33
|
-
|
metadata
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: embedded_localization
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.4.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tilo Sloboda
|
|
8
|
-
autorequire:
|
|
9
8
|
bindir: bin
|
|
10
9
|
cert_chain: []
|
|
11
|
-
date:
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
12
11
|
dependencies:
|
|
13
12
|
- !ruby/object:Gem::Dependency
|
|
14
|
-
name:
|
|
13
|
+
name: rspec
|
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
|
16
15
|
requirements:
|
|
17
16
|
- - ">="
|
|
@@ -25,7 +24,7 @@ dependencies:
|
|
|
25
24
|
- !ruby/object:Gem::Version
|
|
26
25
|
version: '0'
|
|
27
26
|
- !ruby/object:Gem::Dependency
|
|
28
|
-
name:
|
|
27
|
+
name: simplecov
|
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
|
30
29
|
requirements:
|
|
31
30
|
- - ">="
|
|
@@ -82,18 +81,14 @@ dependencies:
|
|
|
82
81
|
version: '0'
|
|
83
82
|
description: 'Rails I18n: a very lightweight tool to allow you to transparently store
|
|
84
83
|
multiple translations of attributes directly inside each DB record -- no extra database
|
|
85
|
-
tables needed to store the localization data!
|
|
84
|
+
tables needed to store the localization data! All translations of a record live
|
|
85
|
+
in one column: a YAML text column, a json/jsonb column, or a PostgreSQL hstore column.'
|
|
86
86
|
email:
|
|
87
87
|
- tilo.sloboda@gmail.com
|
|
88
88
|
executables: []
|
|
89
89
|
extensions: []
|
|
90
90
|
extra_rdoc_files: []
|
|
91
91
|
files:
|
|
92
|
-
- ".github/dependabot.yml"
|
|
93
|
-
- ".github/workflows/codeql-analysis.yml"
|
|
94
|
-
- ".github/workflows/ruby.yml"
|
|
95
|
-
- ".gitignore"
|
|
96
|
-
- ".rspec"
|
|
97
92
|
- CHANGELOG.md
|
|
98
93
|
- Gemfile
|
|
99
94
|
- README.md
|
|
@@ -104,14 +99,9 @@ files:
|
|
|
104
99
|
- lib/embedded_localization/active_record/act_macro.rb
|
|
105
100
|
- lib/embedded_localization/active_record/class_methods.rb
|
|
106
101
|
- lib/embedded_localization/active_record/instance_methods.rb
|
|
102
|
+
- lib/embedded_localization/storage/hstore.rb
|
|
103
|
+
- lib/embedded_localization/storage/json.rb
|
|
107
104
|
- lib/embedded_localization/version.rb
|
|
108
|
-
- lib/extensions/hash.rb
|
|
109
|
-
- spec/embedded_localization/native_column_spec.rb
|
|
110
|
-
- spec/embedded_localization/simple_model_spec.rb
|
|
111
|
-
- spec/models.rb
|
|
112
|
-
- spec/schema.rb
|
|
113
|
-
- spec/spec.opts
|
|
114
|
-
- spec/spec_helper.rb
|
|
115
105
|
homepage: https://github.com/tilo/embedded_localization
|
|
116
106
|
licenses:
|
|
117
107
|
- MIT
|
|
@@ -119,7 +109,7 @@ metadata:
|
|
|
119
109
|
homepage_uri: https://github.com/tilo/embedded_localization
|
|
120
110
|
source_code_uri: https://github.com/tilo/embedded_localization
|
|
121
111
|
changelog_uri: https://github.com/tilo/embedded_localization/blob/main/CHANGELOG.md
|
|
122
|
-
|
|
112
|
+
bug_tracker_uri: https://github.com/tilo/embedded_localization/issues
|
|
123
113
|
rdoc_options: []
|
|
124
114
|
require_paths:
|
|
125
115
|
- lib
|
|
@@ -134,14 +124,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
134
124
|
- !ruby/object:Gem::Version
|
|
135
125
|
version: '0'
|
|
136
126
|
requirements: []
|
|
137
|
-
rubygems_version:
|
|
138
|
-
signing_key:
|
|
127
|
+
rubygems_version: 4.0.17
|
|
139
128
|
specification_version: 4
|
|
140
129
|
summary: 'Rails I18n: library for embedded ActiveRecord model/data translation'
|
|
141
|
-
test_files:
|
|
142
|
-
- spec/embedded_localization/native_column_spec.rb
|
|
143
|
-
- spec/embedded_localization/simple_model_spec.rb
|
|
144
|
-
- spec/models.rb
|
|
145
|
-
- spec/schema.rb
|
|
146
|
-
- spec/spec.opts
|
|
147
|
-
- spec/spec_helper.rb
|
|
130
|
+
test_files: []
|
data/.github/dependabot.yml
DELETED
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
# For most projects, this workflow file will not need changing; you simply need
|
|
2
|
-
# to commit it to your repository.
|
|
3
|
-
#
|
|
4
|
-
# You may wish to alter this file to override the set of languages analyzed,
|
|
5
|
-
# or to provide custom queries or build logic.
|
|
6
|
-
#
|
|
7
|
-
# ******** NOTE ********
|
|
8
|
-
# We have attempted to detect the languages in your repository. Please check
|
|
9
|
-
# the `language` matrix defined below to confirm you have the correct set of
|
|
10
|
-
# supported CodeQL languages.
|
|
11
|
-
#
|
|
12
|
-
name: "CodeQL"
|
|
13
|
-
|
|
14
|
-
on:
|
|
15
|
-
push:
|
|
16
|
-
branches: [ "main" ]
|
|
17
|
-
pull_request:
|
|
18
|
-
# The branches below must be a subset of the branches above
|
|
19
|
-
branches: [ "main" ]
|
|
20
|
-
schedule:
|
|
21
|
-
- cron: '39 11 * * 2'
|
|
22
|
-
|
|
23
|
-
jobs:
|
|
24
|
-
analyze:
|
|
25
|
-
name: Analyze
|
|
26
|
-
runs-on: ubuntu-latest
|
|
27
|
-
permissions:
|
|
28
|
-
actions: read
|
|
29
|
-
contents: read
|
|
30
|
-
security-events: write
|
|
31
|
-
|
|
32
|
-
strategy:
|
|
33
|
-
fail-fast: false
|
|
34
|
-
matrix:
|
|
35
|
-
language: [ 'ruby' ]
|
|
36
|
-
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
|
37
|
-
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
|
38
|
-
|
|
39
|
-
steps:
|
|
40
|
-
- name: Checkout repository
|
|
41
|
-
uses: actions/checkout@v4
|
|
42
|
-
|
|
43
|
-
# Initializes the CodeQL tools for scanning.
|
|
44
|
-
- name: Initialize CodeQL
|
|
45
|
-
uses: github/codeql-action/init@v3
|
|
46
|
-
with:
|
|
47
|
-
languages: ${{ matrix.language }}
|
|
48
|
-
# If you wish to specify custom queries, you can do so here or in a config file.
|
|
49
|
-
# By default, queries listed here will override any specified in a config file.
|
|
50
|
-
# Prefix the list here with "+" to use these queries and those in the config file.
|
|
51
|
-
|
|
52
|
-
# Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
|
53
|
-
# queries: security-extended,security-and-quality
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
|
57
|
-
# If this step fails, then you should remove it and run the build manually (see below)
|
|
58
|
-
- name: Autobuild
|
|
59
|
-
uses: github/codeql-action/autobuild@v3
|
|
60
|
-
|
|
61
|
-
# ℹ️ Command-line programs to run using the OS shell.
|
|
62
|
-
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
|
|
63
|
-
|
|
64
|
-
# If the Autobuild fails above, remove it and uncomment the following three lines.
|
|
65
|
-
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
|
|
66
|
-
|
|
67
|
-
# - run: |
|
|
68
|
-
# echo "Run, Build Application using script"
|
|
69
|
-
# ./location_of_script_within_repo/buildscript.sh
|
|
70
|
-
|
|
71
|
-
- name: Perform CodeQL Analysis
|
|
72
|
-
uses: github/codeql-action/analyze@v3
|
data/.github/workflows/ruby.yml
DELETED
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
# install dependencies and run tests
|
|
2
|
-
# https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
|
3
|
-
|
|
4
|
-
name: Ruby
|
|
5
|
-
|
|
6
|
-
on:
|
|
7
|
-
push:
|
|
8
|
-
branches:
|
|
9
|
-
- main
|
|
10
|
-
|
|
11
|
-
pull_request:
|
|
12
|
-
|
|
13
|
-
jobs:
|
|
14
|
-
test_matrix:
|
|
15
|
-
|
|
16
|
-
strategy:
|
|
17
|
-
fail-fast: false
|
|
18
|
-
matrix:
|
|
19
|
-
os:
|
|
20
|
-
- ubuntu
|
|
21
|
-
- macos
|
|
22
|
-
ruby:
|
|
23
|
-
- 2.5
|
|
24
|
-
- 2.6
|
|
25
|
-
- 2.7
|
|
26
|
-
- "3.0"
|
|
27
|
-
- 3.1
|
|
28
|
-
- 3.2
|
|
29
|
-
- 3.3
|
|
30
|
-
- head
|
|
31
|
-
- truffleruby
|
|
32
|
-
- truffleruby-head
|
|
33
|
-
- mingw
|
|
34
|
-
- jruby
|
|
35
|
-
- jruby-head
|
|
36
|
-
exclude:
|
|
37
|
-
- { os: ubuntu, ruby: mingw }
|
|
38
|
-
- { os: macos, ruby: mingw }
|
|
39
|
-
- { os: windows, ruby: truffleruby }
|
|
40
|
-
- { os: windows, ruby: truffleruby-head }
|
|
41
|
-
|
|
42
|
-
runs-on: ${{ matrix.os }}-latest
|
|
43
|
-
|
|
44
|
-
steps:
|
|
45
|
-
- name: clone ${{ github.repository }}
|
|
46
|
-
uses: actions/checkout@v4
|
|
47
|
-
- name: setup Ruby ${{ matrix.ruby }}
|
|
48
|
-
uses: ruby/setup-ruby@v1
|
|
49
|
-
with:
|
|
50
|
-
ruby-version: ${{ matrix.ruby }}
|
|
51
|
-
bundler-cache: true
|
|
52
|
-
env:
|
|
53
|
-
JAVA_OPTS: -Djdk.io.File.enableADS=true
|
|
54
|
-
- name: Run tests
|
|
55
|
-
run: bundle exec rake
|
|
56
|
-
env:
|
|
57
|
-
JAVA_OPTS: -Djdk.io.File.enableADS=true
|
|
58
|
-
|
|
59
|
-
finish:
|
|
60
|
-
runs-on: ubuntu-latest
|
|
61
|
-
needs: [ test_matrix ]
|
|
62
|
-
steps:
|
|
63
|
-
- name: Wait for status checks
|
|
64
|
-
run: echo "All Green!"
|
data/.gitignore
DELETED
data/.rspec
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
--require spec_helper
|
data/lib/extensions/hash.rb
DELETED
|
@@ -1,191 +0,0 @@
|
|
|
1
|
-
# encoding: utf-8
|
|
2
|
-
require 'spec_helper'
|
|
3
|
-
|
|
4
|
-
I18n.locale = :en
|
|
5
|
-
|
|
6
|
-
# e.g. the model "Movie" has :title as a translated field,
|
|
7
|
-
# but also has :title as a native attribute for the model.
|
|
8
|
-
|
|
9
|
-
describe 'model has translated field with attribute of that same name' do
|
|
10
|
-
let(:movie){ Movie.new }
|
|
11
|
-
|
|
12
|
-
describe "basic things that need to work" do
|
|
13
|
-
|
|
14
|
-
it 'reports it translates' do
|
|
15
|
-
Movie.translates?.should be_truthy
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
it 'correctly reports the list of translated_attributes' do
|
|
19
|
-
Movie.translated_attributes.sort.should eq [:description, :title]
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
it 'correctly reports the list of translated_attribute_names' do
|
|
23
|
-
Movie.translated_attribute_names.sort.should eq [:description, :title]
|
|
24
|
-
end
|
|
25
|
-
|
|
26
|
-
it 'correcty shows the translated attribute as translated' do
|
|
27
|
-
Movie.translated?(:title).should be_truthy
|
|
28
|
-
Movie.translated?(:description).should be_truthy
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
it 'correcty shows not translated attribute' do
|
|
32
|
-
Movie.translated?(:other).should be_falsy
|
|
33
|
-
end
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
describe "new DB records" do
|
|
37
|
-
|
|
38
|
-
it 'correctly reports translated_locales for new record' do
|
|
39
|
-
movie.translated_locales.should eq [I18n.default_locale]
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
it 'correctly reports translation_missing for new record' do
|
|
43
|
-
movie.translation_missing.should be_truthy
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
it 'creates the accessor methods' do
|
|
47
|
-
movie.methods.should include(:title)
|
|
48
|
-
movie.methods.should include(:title=)
|
|
49
|
-
movie.methods.should include(:description)
|
|
50
|
-
movie.methods.should include(:description=)
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
it 'correctly reports translated field for new record for default locale' do
|
|
54
|
-
movie.title.should be_nil
|
|
55
|
-
movie.description.should be_nil
|
|
56
|
-
movie.description( I18n.default_locale ).should be_nil
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
it 'correctly reports translated field for new record for other locale' do
|
|
60
|
-
movie.title(:ko).should be_nil
|
|
61
|
-
movie.description(:de).should be_nil
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
it 'correctly reports translation_coverage for new record' do
|
|
65
|
-
movie.translation_coverage.should eq Hash.new
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
it 'correctly reports translation_goverate for attributes of new record' do
|
|
69
|
-
movie.translation_coverage(:title).should eq []
|
|
70
|
-
movie.translation_coverage(:description).should eq []
|
|
71
|
-
end
|
|
72
|
-
|
|
73
|
-
it 'translated_coverage returns nil for not-translated attributes' do
|
|
74
|
-
movie.translation_coverage(:other).should be_nil
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
it 'correctly reports translation_missing for new record' do
|
|
78
|
-
movie.translation_missing.should == {:description=>[:en], :title=>[:en]}
|
|
79
|
-
movie.translation_missing(:title).should eq [:en]
|
|
80
|
-
movie.translation_missing(:description).should eq [:en]
|
|
81
|
-
end
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
describe "DB record with pre-set fields" do
|
|
86
|
-
let(:title_en){ "Blade Runner" }
|
|
87
|
-
let(:blade_runner){ Movie.new(:title => title_en) }
|
|
88
|
-
|
|
89
|
-
it 'correctly shows the attribute for new record' do
|
|
90
|
-
blade_runner.title.should eq title_en
|
|
91
|
-
end
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
describe "updated DB record" do
|
|
96
|
-
let(:title_en){ "Blade Runner" }
|
|
97
|
-
let(:title_ru){'аЕЦСЫХИ ОН КЕГБХЧ'}
|
|
98
|
-
let(:title_tr){"Ölüm takibi"}
|
|
99
|
-
let(:title_de){"Der Blade Runner"}
|
|
100
|
-
let(:blade_runner){ Movie.new(:title => title_en) }
|
|
101
|
-
|
|
102
|
-
describe 'updating just default locale' do
|
|
103
|
-
|
|
104
|
-
before :each do
|
|
105
|
-
movie.title = title_en
|
|
106
|
-
movie.description = "an awesome movie"
|
|
107
|
-
movie.save
|
|
108
|
-
movie.reload
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
it 'correctly reports the translated_locales' do
|
|
112
|
-
movie.translated_locales.should eq [:en]
|
|
113
|
-
end
|
|
114
|
-
|
|
115
|
-
# when setting all fields in the default locale's languange:
|
|
116
|
-
it 'correctly reports translation_missing for updated record' do
|
|
117
|
-
movie.translation_missing.should eq Hash.new
|
|
118
|
-
end
|
|
119
|
-
|
|
120
|
-
it 'correctly reports translation_missing for attributes' do
|
|
121
|
-
movie.translation_missing(:title).should eq nil
|
|
122
|
-
movie.translation_missing(:description).should eq nil
|
|
123
|
-
end
|
|
124
|
-
|
|
125
|
-
it 'correctly reports translated_coverage for updated record' do
|
|
126
|
-
movie.translation_coverage.should == {:title=>[:en], :description=>[:en]}
|
|
127
|
-
end
|
|
128
|
-
|
|
129
|
-
it 'correctly reports translated_coverage for attributes' do
|
|
130
|
-
movie.translation_coverage(:title).should eq [:en]
|
|
131
|
-
movie.translation_coverage(:description).should eq [:en]
|
|
132
|
-
end
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
describe 'updating other locales' do
|
|
136
|
-
before :each do
|
|
137
|
-
movie.title = title_en
|
|
138
|
-
movie.description = "an awesome movie"
|
|
139
|
-
I18n.locale = :ru
|
|
140
|
-
movie.title = title_ru
|
|
141
|
-
movie.set_localized_attribute(:title , :tr, title_tr)
|
|
142
|
-
I18n.locale = :de
|
|
143
|
-
movie.description = "ein grossartiger Film"
|
|
144
|
-
I18n.locale = I18n.default_locale # MAKE SURE you switch back to your default loale if you tweak it
|
|
145
|
-
movie.save
|
|
146
|
-
movie.reload
|
|
147
|
-
end
|
|
148
|
-
|
|
149
|
-
it 'correctly reports the translated_locales' do
|
|
150
|
-
movie.translated_locales.should eq [:en, :ru, :tr, :de]
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
it 'can assign the translated field' do
|
|
154
|
-
movie.title = title_en
|
|
155
|
-
movie.save.should be_truthy
|
|
156
|
-
movie.title.should eq title_en
|
|
157
|
-
movie.title(:en).should eq title_en
|
|
158
|
-
end
|
|
159
|
-
|
|
160
|
-
# when setting all fields in additional languanges:
|
|
161
|
-
it 'correctly reports values for updated record via attr(:locale)' do
|
|
162
|
-
movie.title(:tr).should eq title_tr
|
|
163
|
-
end
|
|
164
|
-
|
|
165
|
-
it 'correctly reports values for updated record via getter' do
|
|
166
|
-
movie.get_localized_attribute(:title, :ru).should eq title_ru
|
|
167
|
-
end
|
|
168
|
-
|
|
169
|
-
it 'correctly reports translation_coverage for updated record' do
|
|
170
|
-
# what values are actually present
|
|
171
|
-
movie.translation_coverage.should == {:title=>[:en, :ru, :tr], :description=>[:en, :de]}
|
|
172
|
-
end
|
|
173
|
-
|
|
174
|
-
it 'correctly reports translation_coverage for attributes' do
|
|
175
|
-
movie.translation_coverage(:title).should eq [:en,:ru,:tr]
|
|
176
|
-
movie.translation_coverage(:description).should eq [:en,:de]
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
it 'correctly reports translation_missing for updated record' do
|
|
180
|
-
# what values are missing
|
|
181
|
-
movie.translation_missing.should == {:description=>[:ru, :tr], :title=>[:de]}
|
|
182
|
-
end
|
|
183
|
-
|
|
184
|
-
it 'correctly reports translation_missing for attributes' do
|
|
185
|
-
movie.translation_missing(:title).should eq [:de]
|
|
186
|
-
movie.translation_missing(:description).should eq [:ru,:tr]
|
|
187
|
-
end
|
|
188
|
-
end
|
|
189
|
-
|
|
190
|
-
end
|
|
191
|
-
end
|