releaf-i18n_database 0.2.1

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 (38) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +24 -0
  3. data/app/assets/javascripts/releaf/controllers/releaf/i18n_database/translations.js +22 -0
  4. data/app/assets/stylesheets/releaf/controllers/releaf/i18n_database/translations.scss +95 -0
  5. data/app/builders/releaf/i18n_database/translations/builders_common.rb +13 -0
  6. data/app/builders/releaf/i18n_database/translations/edit_builder.rb +41 -0
  7. data/app/builders/releaf/i18n_database/translations/index_builder.rb +44 -0
  8. data/app/builders/releaf/i18n_database/translations/table_builder.rb +31 -0
  9. data/app/controllers/releaf/i18n_database/translations_controller.rb +171 -0
  10. data/app/lib/releaf/i18n_database/translations_importer.rb +72 -0
  11. data/app/lib/releaf/i18n_database/translations_utilities.rb +66 -0
  12. data/app/models/releaf/i18n_database/translation.rb +17 -0
  13. data/app/models/releaf/i18n_database/translation_data.rb +11 -0
  14. data/app/views/releaf/i18n_database/translations/_form_fields.haml +40 -0
  15. data/app/views/releaf/i18n_database/translations/export.xlsx.axlsx +24 -0
  16. data/lib/releaf-i18n_database.rb +5 -0
  17. data/lib/releaf/i18n_database/backend.rb +169 -0
  18. data/lib/releaf/i18n_database/builders_autoload.rb +10 -0
  19. data/lib/releaf/i18n_database/engine.rb +36 -0
  20. data/lib/releaf/i18n_database/humanize_missing_translations.rb +15 -0
  21. data/releaf-i18n_database.gemspec +21 -0
  22. data/spec/builders/translations/builder_common_spec.rb +39 -0
  23. data/spec/builders/translations/edit_builder_spec.rb +93 -0
  24. data/spec/builders/translations/index_builder_spec.rb +96 -0
  25. data/spec/builders/translations/table_builder_spec.rb +68 -0
  26. data/spec/controllers/i18n_backend/translations_controller_spec.rb +157 -0
  27. data/spec/features/translations_spec.rb +162 -0
  28. data/spec/fixtures/all_translations_exported.xlsx +0 -0
  29. data/spec/fixtures/time.formats.xlsx +0 -0
  30. data/spec/fixtures/translations_import.xlsx +0 -0
  31. data/spec/fixtures/unsupported_import_file.png +0 -0
  32. data/spec/lib/i18n_database/backend_spec.rb +337 -0
  33. data/spec/lib/i18n_database/humanize_missing_translations_spec.rb +18 -0
  34. data/spec/lib/i18n_database/translations_importer_spec.rb +17 -0
  35. data/spec/lib/i18n_database/translations_utilities_spec.rb +175 -0
  36. data/spec/models/i18n_database/translation_data_spec.rb +13 -0
  37. data/spec/models/i18n_database/translation_spec.rb +49 -0
  38. metadata +151 -0
@@ -0,0 +1,18 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::I18nDatabase::HumanizeMissingTranslations do
4
+ describe ".call" do
5
+ context "when exception is I18n::MissingTranslation" do
6
+ it "humanizes missing translations" do
7
+ expect(I18n.t("some.missing translation")).to eq("Missing translation")
8
+ end
9
+ end
10
+
11
+ context "when exception is not I18n::MissingTranslation" do
12
+ it "does not intercept it" do
13
+ allow(I18n::Backend::Transliterator).to receive(:get).and_raise(I18n::ArgumentError)
14
+ expect{I18n.transliterate("error?")}.to raise_error(I18n::ArgumentError)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,17 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::I18nDatabase::TranslationsImporter do
4
+ describe "#initialize" do
5
+ context "when unsupported extension given" do
6
+ it "raises Releaf::TranslationsImporter::UnsupportedFileFormatError" do
7
+ expect{described_class.new("xx", "xx")}.to raise_error(described_class::UnsupportedFileFormatError)
8
+ end
9
+ end
10
+
11
+ context "when error raised from Roo" do
12
+ it "raises it" do
13
+ expect{described_class.new("xx", "xls")}.to raise_error(IOError)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,175 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::I18nDatabase::TranslationsUtilities do
4
+ def postgresql?
5
+ ActiveRecord::Base.connection.adapter_name == 'PostgreSQL'
6
+ end
7
+
8
+ describe ".search" do
9
+ before do
10
+ allow(described_class).to receive(:filter_by_text).with("aaa", "xxxx").and_return("bbb")
11
+ allow(described_class).to receive(:filter_only_blank_translations).with("bbb").and_return("ccc")
12
+ allow(described_class).to receive(:filter_only_blank_translations).with("ddd").and_return("eee")
13
+ end
14
+
15
+ context "when search string is present" do
16
+ it "applies search filter to given collection" do
17
+ expect(described_class.search("aaa", "xxxx", true)).to eq("ccc")
18
+ end
19
+ end
20
+
21
+ context "when search string is empty" do
22
+ it "does not apply search filter to given collection" do
23
+ expect(described_class.search("ddd", "", true)).to eq("eee")
24
+ end
25
+ end
26
+
27
+ context "when `only blank` option is true" do
28
+ it "applies `only blank` filter to given collection" do
29
+ expect(described_class.search("aaa", "xxxx", true)).to eq("ccc")
30
+ end
31
+ end
32
+
33
+ context "when `only blank` option is other than true" do
34
+ it "does not apply `only blank` filter to given collection" do
35
+ expect(described_class.search("aaa", "xxxx", false)).to eq("bbb")
36
+ end
37
+ end
38
+ end
39
+
40
+ describe ".filter_only_blank_translations" do
41
+ it "returns given collection applied with empty translation data search" do
42
+ collection = Releaf::I18nDatabase::Translation.where("id > 1")
43
+ allow(described_class).to receive(:search_columns).and_return([
44
+ Releaf::I18nDatabase::Translation.arel_table[:key],
45
+ Releaf::I18nDatabase::Translation.arel_table.alias("lv_data")[:localization],
46
+ ])
47
+ if postgresql?
48
+ result = "WHERE (id > 1) AND ((\"releaf_translations\".\"key\" = '' OR \"releaf_translations\".\"key\" IS NULL)"
49
+ result += " OR (\"lv_data\".\"localization\" = '' OR \"lv_data\".\"localization\" IS NULL))"
50
+ else
51
+ result = "WHERE (id > 1) AND ((`releaf_translations`.`key` = '' OR `releaf_translations`.`key` IS NULL)"
52
+ result += " OR (`lv_data`.`localization` = '' OR `lv_data`.`localization` IS NULL))"
53
+ end
54
+ expect(described_class.filter_only_blank_translations(collection).to_sql).to end_with(result)
55
+ end
56
+ end
57
+
58
+ describe ".filter_by_text" do
59
+ it "returns collection with grouped column searches" do
60
+ collection = Releaf::I18nDatabase::Translation.where("id > 1")
61
+ allow(described_class).to receive(:column_searches).with("redx").and_return([
62
+ "id = 8 AND id = 2",
63
+ "id = 9 AND id = 19",
64
+ ])
65
+ result = "WHERE (id > 1) AND ((id = 8 AND id = 2) OR (id = 9 AND id = 19))"
66
+ expect(described_class.filter_by_text(collection, "redx").to_sql).to end_with(result)
67
+ end
68
+ end
69
+
70
+ describe ".column_searches" do
71
+ it "return array with column based searches" do
72
+ allow(described_class).to receive(:search_columns).and_return([
73
+ Releaf::I18nDatabase::Translation.arel_table[:key],
74
+ Releaf::I18nDatabase::Translation.arel_table.alias("lv_data")[:localization],
75
+ ])
76
+ allow(described_class).to receive(:escape_search_string).with("red").twice.and_return("escaped_red")
77
+ allow(described_class).to receive(:escape_search_string).with("car").twice.and_return("escaped_car")
78
+ if postgresql?
79
+ result = ["\"releaf_translations\".\"key\" ILIKE '%escaped_red%' AND \"releaf_translations\".\"key\" ILIKE '%escaped_car%'",
80
+ "\"lv_data\".\"localization\" ILIKE '%escaped_red%' AND \"lv_data\".\"localization\" ILIKE '%escaped_car%'"]
81
+ else
82
+ result = ["`releaf_translations`.`key` LIKE '%escaped_red%' AND `releaf_translations`.`key` LIKE '%escaped_car%'",
83
+ "`lv_data`.`localization` LIKE '%escaped_red%' AND `lv_data`.`localization` LIKE '%escaped_car%'"]
84
+ end
85
+ expect(described_class.column_searches(" red car ")).to eq(result)
86
+ end
87
+ end
88
+
89
+ describe ".search_columns" do
90
+ it "returns array with translation key arel attribute and locale tables localization attributes" do
91
+ allow(described_class).to receive(:locale_tables).and_return(
92
+ de: Releaf::I18nDatabase::TranslationData.arel_table.alias("de_data"),
93
+ lv: Releaf::I18nDatabase::TranslationData.arel_table.alias("lv_data"),
94
+ en: Releaf::I18nDatabase::TranslationData.arel_table.alias("en_data")
95
+ )
96
+
97
+ result = [
98
+ Releaf::I18nDatabase::Translation.arel_table[:key],
99
+ Releaf::I18nDatabase::TranslationData.arel_table.alias("de_data")[:localization],
100
+ Releaf::I18nDatabase::TranslationData.arel_table.alias("lv_data")[:localization],
101
+ Releaf::I18nDatabase::TranslationData.arel_table.alias("en_data")[:localization]
102
+ ]
103
+ expect(described_class.search_columns).to eq(result)
104
+ end
105
+ end
106
+
107
+ describe ".escape_search_string" do
108
+ it "returns escaped search string with escaped `%` and `_` chars" do
109
+ expect(described_class.escape_search_string("k % _ x")).to eq("k \\% \\_ x")
110
+ end
111
+ end
112
+
113
+ describe ".locale_tables" do
114
+ it "returns array with arel aliased locale tables" do
115
+ allow(Releaf.application.config).to receive(:all_locales).and_return([:de, :en])
116
+ result = {
117
+ de: Releaf::I18nDatabase::TranslationData.arel_table.alias("de_data"),
118
+ en: Releaf::I18nDatabase::TranslationData.arel_table.alias("en_data")
119
+ }
120
+ expect(described_class.locale_tables).to eq(result)
121
+ end
122
+ end
123
+
124
+ describe ".include_localizations" do
125
+ it "returns given collection with included joins and overrided selects" do
126
+ allow(described_class).to receive(:localization_include_joins).and_return(["a", "b"])
127
+ allow(described_class).to receive(:localization_include_selects).and_return("x")
128
+ if postgresql?
129
+ result = "SELECT x FROM \"releaf_translations\" a b"
130
+ else
131
+ result = "SELECT x FROM `releaf_translations` a b"
132
+ end
133
+ expect(described_class.include_localizations(Releaf::I18nDatabase::Translation).to_sql).to eq(result)
134
+ end
135
+ end
136
+
137
+ describe ".localization_include_joins" do
138
+ it "returns array with locales translation table joins" do
139
+ allow(described_class).to receive(:locale_tables).and_return(
140
+ de: Releaf::I18nDatabase::TranslationData.arel_table.alias("de_data"),
141
+ lv: Releaf::I18nDatabase::TranslationData.arel_table.alias("lv_data"),
142
+ en: Releaf::I18nDatabase::TranslationData.arel_table.alias("en_data")
143
+ )
144
+ result = ["LEFT JOIN releaf_translation_data AS de_data ON de_data.translation_id = releaf_translations.id AND de_data.lang = 'de'",
145
+ "LEFT JOIN releaf_translation_data AS lv_data ON lv_data.translation_id = releaf_translations.id AND lv_data.lang = 'lv'",
146
+ "LEFT JOIN releaf_translation_data AS en_data ON en_data.translation_id = releaf_translations.id AND en_data.lang = 'en'"]
147
+ expect(described_class.localization_include_joins).to eq(result)
148
+ end
149
+ end
150
+
151
+ describe ".localization_include_selects" do
152
+ it "returns all base table columns and each locale translated values and ids" do
153
+ allow(described_class).to receive(:localization_include_locales_columns).and_return([
154
+ "de_data.localization AS de_localization",
155
+ "de_data.id AS de_localization_id"
156
+ ])
157
+ result = "releaf_translations.*, de_data.localization AS de_localization, de_data.id AS de_localization_id"
158
+ expect(described_class.localization_include_selects).to eq(result)
159
+ end
160
+ end
161
+
162
+ describe ".localization_include_locales_columns" do
163
+ it "returns locales translated values columns and ids" do
164
+ allow(described_class).to receive(:locale_tables).and_return(
165
+ de: Releaf::I18nDatabase::TranslationData.arel_table.alias("de_data"),
166
+ lv: Releaf::I18nDatabase::TranslationData.arel_table.alias("lv_data"),
167
+ en: Releaf::I18nDatabase::TranslationData.arel_table.alias("en_data")
168
+ )
169
+ result = ["de_data.localization AS de_localization", "de_data.id AS de_localization_id",
170
+ "lv_data.localization AS lv_localization", "lv_data.id AS lv_localization_id",
171
+ "en_data.localization AS en_localization", "en_data.id AS en_localization_id"]
172
+ expect(described_class.localization_include_locales_columns).to eq(result)
173
+ end
174
+ end
175
+ end
@@ -0,0 +1,13 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::I18nDatabase::TranslationData do
4
+
5
+ it { is_expected.to validate_presence_of(:translation) }
6
+ it { is_expected.to validate_presence_of(:lang) }
7
+ it { is_expected.to validate_length_of(:lang).is_at_most(5) }
8
+ it {
9
+ FactoryGirl.create(:translation_data)
10
+ is_expected.to validate_uniqueness_of(:translation_id).scoped_to([:lang])
11
+ }
12
+ it { is_expected.to belong_to(:translation) }
13
+ end
@@ -0,0 +1,49 @@
1
+ require "rails_helper"
2
+
3
+ describe Releaf::I18nDatabase::Translation do
4
+
5
+ it { is_expected.to validate_presence_of(:key) }
6
+ it { is_expected.to validate_length_of(:key).is_at_most(255) }
7
+ it do
8
+ FactoryGirl.create(:translation)
9
+ is_expected.to validate_uniqueness_of(:key)
10
+ end
11
+ it { is_expected.to have_many(:translation_data).dependent(:destroy) }
12
+ it { is_expected.to accept_nested_attributes_for(:translation_data).allow_destroy(true) }
13
+
14
+
15
+ before do
16
+ allow(Releaf.application.config).to receive(:available_locales) { ["de", "en"] }
17
+ allow(Releaf.application.config).to receive(:available_admin_locales) { ["lv"] }
18
+
19
+ @translation = FactoryGirl.create(:translation, :key => 'test.apple')
20
+ FactoryGirl.create(:translation_data, :localization => 'apple', :translation => @translation, :lang => "en")
21
+ FactoryGirl.create(:translation_data, :localization => 'apfel', :translation => @translation, :lang => "de")
22
+
23
+ I18n.backend.reload_cache
24
+ end
25
+
26
+ describe "translation" do
27
+ it "has relation to translation data" do
28
+ expect(@translation.translation_data.size).to eq(2)
29
+ end
30
+
31
+ it "destroys translation data when destroying translation itself" do
32
+ expect{ @translation.destroy }.to change{ Releaf::I18nDatabase::TranslationData.all.count }.from(2).to(0)
33
+ end
34
+ end
35
+
36
+ describe "#locale_value" do
37
+ it "returns translated value for given locale" do
38
+ expect(@translation.locale_value("en")).to eq("apple")
39
+ expect(@translation.locale_value("de")).to eq("apfel")
40
+ expect(@translation.locale_value("lt")).to eq(nil)
41
+ end
42
+
43
+ it "caches translated values with first call" do
44
+ expect(@translation.locale_value("en")).to eq("apple")
45
+ Releaf::I18nDatabase::TranslationData.destroy_all
46
+ expect(@translation.locale_value("de")).to eq("apfel")
47
+ end
48
+ end
49
+ end
metadata ADDED
@@ -0,0 +1,151 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: releaf-i18n_database
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.1
5
+ platform: ruby
6
+ authors:
7
+ - CubeSystems
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-01-26 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: releaf-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 0.2.1
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '='
25
+ - !ruby/object:Gem::Version
26
+ version: 0.2.1
27
+ - !ruby/object:Gem::Dependency
28
+ name: twitter_cldr
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: axlsx_rails
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: 0.3.0
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: 0.3.0
55
+ - !ruby/object:Gem::Dependency
56
+ name: roo
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: i18n database backend for releaf
70
+ email: info@cubesystems.lv
71
+ executables: []
72
+ extensions: []
73
+ extra_rdoc_files: []
74
+ files:
75
+ - LICENSE
76
+ - app/assets/javascripts/releaf/controllers/releaf/i18n_database/translations.js
77
+ - app/assets/stylesheets/releaf/controllers/releaf/i18n_database/translations.scss
78
+ - app/builders/releaf/i18n_database/translations/builders_common.rb
79
+ - app/builders/releaf/i18n_database/translations/edit_builder.rb
80
+ - app/builders/releaf/i18n_database/translations/index_builder.rb
81
+ - app/builders/releaf/i18n_database/translations/table_builder.rb
82
+ - app/controllers/releaf/i18n_database/translations_controller.rb
83
+ - app/lib/releaf/i18n_database/translations_importer.rb
84
+ - app/lib/releaf/i18n_database/translations_utilities.rb
85
+ - app/models/releaf/i18n_database/translation.rb
86
+ - app/models/releaf/i18n_database/translation_data.rb
87
+ - app/views/releaf/i18n_database/translations/_form_fields.haml
88
+ - app/views/releaf/i18n_database/translations/export.xlsx.axlsx
89
+ - lib/releaf-i18n_database.rb
90
+ - lib/releaf/i18n_database/backend.rb
91
+ - lib/releaf/i18n_database/builders_autoload.rb
92
+ - lib/releaf/i18n_database/engine.rb
93
+ - lib/releaf/i18n_database/humanize_missing_translations.rb
94
+ - releaf-i18n_database.gemspec
95
+ - spec/builders/translations/builder_common_spec.rb
96
+ - spec/builders/translations/edit_builder_spec.rb
97
+ - spec/builders/translations/index_builder_spec.rb
98
+ - spec/builders/translations/table_builder_spec.rb
99
+ - spec/controllers/i18n_backend/translations_controller_spec.rb
100
+ - spec/features/translations_spec.rb
101
+ - spec/fixtures/all_translations_exported.xlsx
102
+ - spec/fixtures/time.formats.xlsx
103
+ - spec/fixtures/translations_import.xlsx
104
+ - spec/fixtures/unsupported_import_file.png
105
+ - spec/lib/i18n_database/backend_spec.rb
106
+ - spec/lib/i18n_database/humanize_missing_translations_spec.rb
107
+ - spec/lib/i18n_database/translations_importer_spec.rb
108
+ - spec/lib/i18n_database/translations_utilities_spec.rb
109
+ - spec/models/i18n_database/translation_data_spec.rb
110
+ - spec/models/i18n_database/translation_spec.rb
111
+ homepage: https://github.com/cubesystems/releaf
112
+ licenses: []
113
+ metadata: {}
114
+ post_install_message:
115
+ rdoc_options: []
116
+ require_paths:
117
+ - lib
118
+ required_ruby_version: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ version: '0'
123
+ required_rubygems_version: !ruby/object:Gem::Requirement
124
+ requirements:
125
+ - - ">="
126
+ - !ruby/object:Gem::Version
127
+ version: '0'
128
+ requirements: []
129
+ rubyforge_project:
130
+ rubygems_version: 2.4.8
131
+ signing_key:
132
+ specification_version: 4
133
+ summary: i18n database gem for releaf
134
+ test_files:
135
+ - spec/builders/translations/builder_common_spec.rb
136
+ - spec/builders/translations/edit_builder_spec.rb
137
+ - spec/builders/translations/index_builder_spec.rb
138
+ - spec/builders/translations/table_builder_spec.rb
139
+ - spec/controllers/i18n_backend/translations_controller_spec.rb
140
+ - spec/features/translations_spec.rb
141
+ - spec/fixtures/all_translations_exported.xlsx
142
+ - spec/fixtures/time.formats.xlsx
143
+ - spec/fixtures/translations_import.xlsx
144
+ - spec/fixtures/unsupported_import_file.png
145
+ - spec/lib/i18n_database/backend_spec.rb
146
+ - spec/lib/i18n_database/humanize_missing_translations_spec.rb
147
+ - spec/lib/i18n_database/translations_importer_spec.rb
148
+ - spec/lib/i18n_database/translations_utilities_spec.rb
149
+ - spec/models/i18n_database/translation_data_spec.rb
150
+ - spec/models/i18n_database/translation_spec.rb
151
+ has_rdoc: