i18n_yaml_editor 2.0.0 → 2.1.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 +5 -5
- data/bin/i18n_yaml_editor +2 -0
- data/i18n_yaml_editor.gemspec +35 -31
- data/lib/i18n_yaml_editor.rb +0 -1
- data/lib/i18n_yaml_editor/app.rb +2 -24
- data/lib/i18n_yaml_editor/store.rb +3 -4
- data/test/unit/test_app_load_translations.rb +52 -0
- data/test/unit/test_app_new.rb +40 -0
- data/test/unit/test_app_start.rb +58 -0
- data/test/unit/test_store_data.rb +40 -0
- data/test/unit/test_store_filter.rb +58 -0
- data/test/unit/test_web.rb +52 -0
- metadata +29 -8
- data/lib/i18n_yaml_editor/core_ext.rb +0 -14
- data/lib/i18n_yaml_editor/transformation.rb +0 -75
- data/test/unit/test_transformation.rb +0 -45
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ad480bea1096f76fac7b6bb42adc82c7ea60c956f4d8c0806e6e5856475acac0
|
4
|
+
data.tar.gz: 2cc8b7ab2f39c9637fa8b5396d8ff968c0951b433e4f037589b3ab35a5be1e26
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bdffd81d20c4651ba5918972ce5d849c13b7bb6f9e994cb283d1445fddfc684a16dea65c14c2dd5f5ab30fc22a315e359cdb9e62e30764351cacc5c427d8a243
|
7
|
+
data.tar.gz: fa83700132f54985f86f6fec20c76e7a1e547eeb3a295ba4df1b3b2cee0bb53ddeb77f18a3e086abe1fc44c48ab0e8db763b73c02512b1744bdaf72f12a3285e
|
data/bin/i18n_yaml_editor
CHANGED
data/i18n_yaml_editor.gemspec
CHANGED
@@ -3,49 +3,53 @@
|
|
3
3
|
# rubocop:disable Metrics/BlockLength
|
4
4
|
Gem::Specification.new do |s|
|
5
5
|
s.name = 'i18n_yaml_editor'
|
6
|
-
s.version = '2.
|
7
|
-
s.date = '
|
6
|
+
s.version = '2.1.0'
|
7
|
+
s.date = '2018-05-04'
|
8
8
|
s.summary = 'I18n Yaml Editor'
|
9
9
|
s.email = 'wolfgang.teuber@sage.com'
|
10
10
|
s.homepage = 'http://github.com/Sage/i18n_yaml_editor'
|
11
11
|
s.description = 'I18n Yaml Editor'
|
12
12
|
s.authors = ['Harry Vangberg', 'Wolfgang Teuber']
|
13
13
|
s.executables << 'i18n_yaml_editor'
|
14
|
-
s.files = [
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
'views/layout.erb',
|
34
|
-
'views/translations.html.erb'
|
14
|
+
s.files = %w[
|
15
|
+
README.md
|
16
|
+
Rakefile
|
17
|
+
i18n_yaml_editor.gemspec
|
18
|
+
bin/i18n_yaml_editor
|
19
|
+
lib/i18n_yaml_editor.rb
|
20
|
+
lib/i18n_yaml_editor/app.rb
|
21
|
+
lib/i18n_yaml_editor/category.rb
|
22
|
+
lib/i18n_yaml_editor/key.rb
|
23
|
+
lib/i18n_yaml_editor/store.rb
|
24
|
+
lib/i18n_yaml_editor/filter.rb
|
25
|
+
lib/i18n_yaml_editor/update.rb
|
26
|
+
lib/i18n_yaml_editor/cast.rb
|
27
|
+
lib/i18n_yaml_editor/translation.rb
|
28
|
+
lib/i18n_yaml_editor/web.rb
|
29
|
+
views/categories.html.erb
|
30
|
+
views/debug.html.erb
|
31
|
+
views/layout.erb
|
32
|
+
views/translations.html.erb
|
35
33
|
]
|
36
|
-
s.test_files = [
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
34
|
+
s.test_files = %w[
|
35
|
+
test/test_helper.rb
|
36
|
+
test/unit/test_app.rb
|
37
|
+
test/unit/test_app_load_translations.rb
|
38
|
+
test/unit/test_app_new.rb
|
39
|
+
test/unit/test_app_start.rb
|
40
|
+
test/unit/test_category.rb
|
41
|
+
test/unit/test_key.rb
|
42
|
+
test/unit/test_store.rb
|
43
|
+
test/unit/test_store_data.rb
|
44
|
+
test/unit/test_store_filter.rb
|
45
|
+
test/unit/test_translation.rb
|
46
|
+
test/unit/test_web.rb
|
44
47
|
]
|
45
48
|
s.add_dependency 'activesupport', '>= 4.0.2'
|
46
49
|
s.add_dependency 'cuba', '>= 3'
|
47
50
|
s.add_dependency 'psych', '>= 1.3.4'
|
48
51
|
s.add_dependency 'tilt', '>= 1.3'
|
52
|
+
s.add_dependency 'yaml_normalizer', '>= 0'
|
49
53
|
|
50
54
|
s.add_development_dependency 'awesome_print'
|
51
55
|
s.add_development_dependency 'cane'
|
data/lib/i18n_yaml_editor.rb
CHANGED
data/lib/i18n_yaml_editor/app.rb
CHANGED
@@ -6,7 +6,6 @@ require 'active_support/all'
|
|
6
6
|
|
7
7
|
require 'i18n_yaml_editor/web'
|
8
8
|
require 'i18n_yaml_editor/store'
|
9
|
-
require 'i18n_yaml_editor/core_ext'
|
10
9
|
|
11
10
|
module I18nYamlEditor
|
12
11
|
# App provides I18n Yaml Editor's top-level functionality:
|
@@ -58,8 +57,9 @@ module I18nYamlEditor
|
|
58
57
|
store.update(translations)
|
59
58
|
changes = files(translations: translations)
|
60
59
|
changes.each do |file, yaml|
|
60
|
+
yaml.extend(YamlNormalizer::Ext::SortByKey)
|
61
61
|
File.open(file, 'w', encoding: 'utf-8') do |f|
|
62
|
-
f.puts
|
62
|
+
f.puts yaml.sort_by_key.to_yaml
|
63
63
|
end
|
64
64
|
end
|
65
65
|
end
|
@@ -99,27 +99,5 @@ module I18nYamlEditor
|
|
99
99
|
end
|
100
100
|
end.nil?
|
101
101
|
end
|
102
|
-
|
103
|
-
def normalize(yaml)
|
104
|
-
i18n_yaml = yaml.with_indifferent_access.to_hash.to_yaml
|
105
|
-
i18n_yaml_lines = i18n_yaml.split(/\n/).reject { |e| e == '' }[1..-1]
|
106
|
-
normalize_empty_lines(i18n_yaml_lines) * "\n"
|
107
|
-
end
|
108
|
-
|
109
|
-
def normalize_empty_lines(i18n_yaml_lines)
|
110
|
-
yaml_ary = []
|
111
|
-
i18n_yaml_lines.each_with_index do |line, idx|
|
112
|
-
yaml_ary << line
|
113
|
-
yaml_ary << '' if add_empty_line?(i18n_yaml_lines, line, idx)
|
114
|
-
end
|
115
|
-
yaml_ary
|
116
|
-
end
|
117
|
-
|
118
|
-
def add_empty_line?(process, line, idx)
|
119
|
-
return if process[idx + 1].nil?
|
120
|
-
this_line_spcs = line[/\A\s*/].length
|
121
|
-
next_line_spcs = process[idx + 1][/\A\s*/].length
|
122
|
-
this_line_spcs - next_line_spcs > 2
|
123
|
-
end
|
124
102
|
end
|
125
103
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
require 'set'
|
4
4
|
require 'pathname'
|
5
|
+
require 'yaml_normalizer'
|
5
6
|
|
6
|
-
require 'i18n_yaml_editor/transformation'
|
7
7
|
require 'i18n_yaml_editor/filter'
|
8
8
|
require 'i18n_yaml_editor/update'
|
9
9
|
require 'i18n_yaml_editor/category'
|
@@ -16,7 +16,6 @@ module I18nYamlEditor
|
|
16
16
|
|
17
17
|
# Store keeps all i18n data
|
18
18
|
class Store
|
19
|
-
include Transformation
|
20
19
|
include Filter
|
21
20
|
include Update
|
22
21
|
|
@@ -74,7 +73,7 @@ module I18nYamlEditor
|
|
74
73
|
|
75
74
|
# Adds a translation for every entry in a given yaml hash
|
76
75
|
def from_yaml(yaml, file = nil)
|
77
|
-
translations =
|
76
|
+
translations = yaml.extend(YamlNormalizer::Ext::Namespaced).namespaced
|
78
77
|
translations.each do |name, text|
|
79
78
|
translation = Translation.new(name: name, text: text, file: file)
|
80
79
|
add_translation(translation)
|
@@ -90,7 +89,7 @@ module I18nYamlEditor
|
|
90
89
|
translations.each do |translation|
|
91
90
|
file_result[translation.name] = translation.text
|
92
91
|
end
|
93
|
-
result[file] =
|
92
|
+
result[file] = file_result.extend(YamlNormalizer::Ext::Nested).nested
|
94
93
|
end
|
95
94
|
result
|
96
95
|
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'i18n_yaml_editor/app'
|
5
|
+
|
6
|
+
class TestApp < Minitest::Test
|
7
|
+
def test_load_translations_error
|
8
|
+
Dir.mktmpdir do |dir|
|
9
|
+
file = dir + '/does_not_exist.yml'
|
10
|
+
assert_output('', "No valid translation file given\n") do
|
11
|
+
App.new(file).load_translations
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_load_translations_dir
|
17
|
+
store_from_yaml = lambda do |yaml, file|
|
18
|
+
assert_equal(yaml['en']['session']['create']['logged_in'], 'Welcome!')
|
19
|
+
assert_match(%r{/session\.en\.yml\z}, file)
|
20
|
+
end
|
21
|
+
|
22
|
+
Dir.mktmpdir do |dir|
|
23
|
+
FileUtils.copy './example/session.en.yml', dir
|
24
|
+
@app = App.new(dir)
|
25
|
+
@app.store.stub(:from_yaml, store_from_yaml) { @app.load_translations }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_load_translations_file_list
|
30
|
+
Dir.mktmpdir do |dir|
|
31
|
+
FileUtils.copy './example/session.en.yml', dir
|
32
|
+
list_path = File.join(dir, 'file_list')
|
33
|
+
File.open(list_path, 'w') { |f| f.write(Dir[dir + '/*.yml'] * "\n") }
|
34
|
+
@app = App.new(list_path)
|
35
|
+
@app.load_translations
|
36
|
+
end
|
37
|
+
assert @app.store.translations.key?('en.session.create.logged_in')
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_load_translations_translation_file
|
41
|
+
store_from_yaml = lambda do |yaml, file|
|
42
|
+
assert_equal(yaml['en']['session']['create']['logged_in'], 'Welcome!')
|
43
|
+
assert_match(%r{/session\.en\.yml\z}, file)
|
44
|
+
end
|
45
|
+
|
46
|
+
Dir.mktmpdir do |dir|
|
47
|
+
FileUtils.copy './example/session.en.yml', dir
|
48
|
+
@app = App.new(dir + '/session.en.yml')
|
49
|
+
@app.store.stub(:from_yaml, store_from_yaml) { @app.load_translations }
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'i18n_yaml_editor/app'
|
5
|
+
|
6
|
+
class TestApp < Minitest::Test
|
7
|
+
def test_new_no_path_given
|
8
|
+
assert_raises(ArgumentError) { App.new }
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_new_given_path
|
12
|
+
app = App.new('my_path')
|
13
|
+
assert_match(/my_path\z/, app.instance_variable_get(:@path))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_new_default_port
|
17
|
+
app = App.new('')
|
18
|
+
assert_equal 5050, app.instance_variable_get(:@port)
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_new_given_port
|
22
|
+
app = App.new('', 3333)
|
23
|
+
assert_equal 3333, app.instance_variable_get(:@port)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_new_store
|
27
|
+
app = App.new('')
|
28
|
+
refute_nil app.instance_variable_get(:@store)
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_new_store_accessor
|
32
|
+
app = App.new('')
|
33
|
+
assert_equal app.store, app.instance_variable_get(:@store)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_new_exposure
|
37
|
+
app = App.new('')
|
38
|
+
assert_equal(I18nYamlEditor.app, app)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'i18n_yaml_editor/app'
|
5
|
+
|
6
|
+
class TestApp < Minitest::Test
|
7
|
+
def setup
|
8
|
+
@app = App.new('.')
|
9
|
+
@fake_load_translations = -> { raise 'called load_translations' }
|
10
|
+
@fake_store_create_missing_keys = -> { raise 'called create_missing_keys' }
|
11
|
+
@fake_rack_server_start = lambda do |options|
|
12
|
+
assert_equal({ app: I18nYamlEditor::Web, Port: 5050 }, options)
|
13
|
+
raise 'called rack_server_start'
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def test_start_file_not_found
|
18
|
+
Dir.mktmpdir do |dir|
|
19
|
+
file = dir + '/does_not_exist.yml'
|
20
|
+
@app.stub :load_translations, @fake_load_translations do
|
21
|
+
@app = App.new(file)
|
22
|
+
assert_raises("File #{file} not found.") do
|
23
|
+
@app.start
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_start_load_translations
|
30
|
+
assert_output(/ \* Loading translations from/, '') do
|
31
|
+
@app.stub :load_translations, @fake_load_translations do
|
32
|
+
assert_raises('called load_translations') { @app.start }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_store_create_missing_keys
|
38
|
+
assert_output(/ \* Creating missing translations/, '') do
|
39
|
+
@app.stub :load_translations, nil do
|
40
|
+
@app.store.stub :create_missing_keys, @fake_store_create_missing_keys do
|
41
|
+
assert_raises('called create_missing_keys') { @app.start }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_server_start
|
48
|
+
assert_output(/ \* Starting I18n Yaml Editor at port /, '') do
|
49
|
+
@app.stub :load_translations, nil do
|
50
|
+
@app.store.stub :create_missing_keys, nil do
|
51
|
+
Rack::Server.stub :start, @fake_rack_server_start do
|
52
|
+
assert_raises('called rack_server_start') { @app.start }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'i18n_yaml_editor/store'
|
5
|
+
|
6
|
+
module TestStoreData
|
7
|
+
def self.included(_base)
|
8
|
+
include I18nYamlEditor
|
9
|
+
end
|
10
|
+
|
11
|
+
def init_test_store_1
|
12
|
+
store = Store.new
|
13
|
+
store.add_translation tmp_translation_1
|
14
|
+
store.locales.add('en')
|
15
|
+
store
|
16
|
+
end
|
17
|
+
|
18
|
+
def init_test_store_0
|
19
|
+
store = Store.new
|
20
|
+
store.add_translation tmp_translation_0
|
21
|
+
store.locales.add('en')
|
22
|
+
store
|
23
|
+
end
|
24
|
+
|
25
|
+
def tmp_translation_1
|
26
|
+
Translation.new(
|
27
|
+
name: 'da.app_name',
|
28
|
+
text: 'Oversætter',
|
29
|
+
file: '/tmp/da.yml'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def tmp_translation_0
|
34
|
+
Translation.new(
|
35
|
+
name: 'da.session.login',
|
36
|
+
text: 'Log ind',
|
37
|
+
file: '/tmp/session.da.yml'
|
38
|
+
)
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'i18n_yaml_editor/store'
|
5
|
+
|
6
|
+
class TestStore < Minitest::Test
|
7
|
+
def test_filter_keys_on_key
|
8
|
+
store = Store.new
|
9
|
+
store.add_key(Key.new(name: 'session.login'))
|
10
|
+
store.add_key(Key.new(name: 'session.logout'))
|
11
|
+
|
12
|
+
result = store.filter_keys(key: /login/)
|
13
|
+
|
14
|
+
assert_equal 1, result.size
|
15
|
+
assert_equal %w[session.login], result.keys
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_filter_keys_on_complete
|
19
|
+
store = Store.new
|
20
|
+
[{ name: 'da.session.login', text: 'Log ind' },
|
21
|
+
{ name: 'en.session.login' },
|
22
|
+
{ name: 'da.session.logout', text: 'Log ud' }].each do |translation|
|
23
|
+
store.add_translation Translation.new(translation)
|
24
|
+
end
|
25
|
+
|
26
|
+
result = store.filter_keys(complete: false)
|
27
|
+
|
28
|
+
assert_equal 1, result.size
|
29
|
+
assert_equal %w[session.login], result.keys
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_filter_keys_on_empty
|
33
|
+
store = Store.new
|
34
|
+
store.add_translation Translation.new(name: 'da.session.login',
|
35
|
+
text: 'Log ind')
|
36
|
+
store.add_translation Translation.new(name: 'da.session.logout')
|
37
|
+
|
38
|
+
result = store.filter_keys(empty: true)
|
39
|
+
|
40
|
+
assert_equal 1, result.size
|
41
|
+
assert_equal %w[session.logout], result.keys
|
42
|
+
end
|
43
|
+
|
44
|
+
def test_filter_keys_on_text
|
45
|
+
store = Store.new
|
46
|
+
store.add_translation Translation.new(name: 'da.session.login',
|
47
|
+
text: 'Log ind')
|
48
|
+
store.add_translation Translation.new(name: 'da.session.logout',
|
49
|
+
text: 'Log ud')
|
50
|
+
store.add_translation Translation.new(name: 'da.app.name',
|
51
|
+
text: 'I18n Yaml Editor')
|
52
|
+
|
53
|
+
result = store.filter_keys(text: /Log/)
|
54
|
+
|
55
|
+
assert_equal 2, result.size
|
56
|
+
assert_equal %w[session.login session.logout].sort, result.keys.sort
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'test_helper'
|
4
|
+
require 'i18n_yaml_editor/web'
|
5
|
+
|
6
|
+
# TODO: imprive tests in TestWeb
|
7
|
+
class TestWeb < Minitest::Test
|
8
|
+
include Rack::Test::Methods
|
9
|
+
|
10
|
+
def setup
|
11
|
+
app = nil
|
12
|
+
capture_io { app = App.new('examples') }
|
13
|
+
|
14
|
+
app.load_translations
|
15
|
+
app.store.create_missing_keys
|
16
|
+
I18nYamlEditor.app = app
|
17
|
+
end
|
18
|
+
|
19
|
+
def app
|
20
|
+
Rack::Builder.new Web
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_get_root
|
24
|
+
capture_io { get '/' }
|
25
|
+
|
26
|
+
refute_nil last_response
|
27
|
+
end
|
28
|
+
|
29
|
+
def test_get_root_filter
|
30
|
+
capture_io { get '/', filters: { key: '^app_name' } }
|
31
|
+
|
32
|
+
refute_nil last_response
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_get_debug
|
36
|
+
capture_io { get '/debug' }
|
37
|
+
|
38
|
+
refute_nil last_response
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_get_update
|
42
|
+
capture_io do
|
43
|
+
post '/update', 'filters' => { 'key' => '^day_names' },
|
44
|
+
'translations' => {
|
45
|
+
'da.day_names' => "søndag\r\nmandag\r\nonsdag\r\n"\
|
46
|
+
"torsdag\r\nfredag\r\nlørdag",
|
47
|
+
'en.day_names' => 'lol'
|
48
|
+
}
|
49
|
+
end
|
50
|
+
refute_nil last_response
|
51
|
+
end
|
52
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n_yaml_editor
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Harry Vangberg
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2018-05-04 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
@@ -67,6 +67,20 @@ dependencies:
|
|
67
67
|
- - ">="
|
68
68
|
- !ruby/object:Gem::Version
|
69
69
|
version: '1.3'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: yaml_normalizer
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
70
84
|
- !ruby/object:Gem::Dependency
|
71
85
|
name: awesome_print
|
72
86
|
requirement: !ruby/object:Gem::Requirement
|
@@ -348,21 +362,24 @@ files:
|
|
348
362
|
- lib/i18n_yaml_editor/app.rb
|
349
363
|
- lib/i18n_yaml_editor/cast.rb
|
350
364
|
- lib/i18n_yaml_editor/category.rb
|
351
|
-
- lib/i18n_yaml_editor/core_ext.rb
|
352
365
|
- lib/i18n_yaml_editor/filter.rb
|
353
366
|
- lib/i18n_yaml_editor/key.rb
|
354
367
|
- lib/i18n_yaml_editor/store.rb
|
355
|
-
- lib/i18n_yaml_editor/transformation.rb
|
356
368
|
- lib/i18n_yaml_editor/translation.rb
|
357
369
|
- lib/i18n_yaml_editor/update.rb
|
358
370
|
- lib/i18n_yaml_editor/web.rb
|
359
371
|
- test/test_helper.rb
|
360
372
|
- test/unit/test_app.rb
|
373
|
+
- test/unit/test_app_load_translations.rb
|
374
|
+
- test/unit/test_app_new.rb
|
375
|
+
- test/unit/test_app_start.rb
|
361
376
|
- test/unit/test_category.rb
|
362
377
|
- test/unit/test_key.rb
|
363
378
|
- test/unit/test_store.rb
|
364
|
-
- test/unit/
|
379
|
+
- test/unit/test_store_data.rb
|
380
|
+
- test/unit/test_store_filter.rb
|
365
381
|
- test/unit/test_translation.rb
|
382
|
+
- test/unit/test_web.rb
|
366
383
|
- views/categories.html.erb
|
367
384
|
- views/debug.html.erb
|
368
385
|
- views/layout.erb
|
@@ -386,16 +403,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
386
403
|
version: '0'
|
387
404
|
requirements: []
|
388
405
|
rubyforge_project:
|
389
|
-
rubygems_version: 2.
|
406
|
+
rubygems_version: 2.7.6
|
390
407
|
signing_key:
|
391
408
|
specification_version: 4
|
392
409
|
summary: I18n Yaml Editor
|
393
410
|
test_files:
|
394
411
|
- test/test_helper.rb
|
395
412
|
- test/unit/test_app.rb
|
413
|
+
- test/unit/test_app_load_translations.rb
|
414
|
+
- test/unit/test_app_new.rb
|
415
|
+
- test/unit/test_app_start.rb
|
396
416
|
- test/unit/test_category.rb
|
397
417
|
- test/unit/test_key.rb
|
398
418
|
- test/unit/test_store.rb
|
399
|
-
- test/unit/
|
419
|
+
- test/unit/test_store_data.rb
|
420
|
+
- test/unit/test_store_filter.rb
|
400
421
|
- test/unit/test_translation.rb
|
401
|
-
|
422
|
+
- test/unit/test_web.rb
|
@@ -1,14 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Extend Hash with sort_by_key method
|
4
|
-
class Hash
|
5
|
-
# Sorts entries alphabetically by key
|
6
|
-
def sort_by_key(recursive = false, &block)
|
7
|
-
keys.sort(&block).each_with_object({}) do |key, seed|
|
8
|
-
seed[key] = self[key]
|
9
|
-
if recursive && seed[key].is_a?(Hash)
|
10
|
-
seed[key] = seed[key].sort_by_key(true, &block)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
@@ -1,75 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module I18nYamlEditor
|
4
|
-
# Raised when nesting of I18n keys to a Hash fails
|
5
|
-
class TransformationError < StandardError; end
|
6
|
-
|
7
|
-
# Transformation provides
|
8
|
-
module Transformation
|
9
|
-
# Public: Converts a deep hash to one level by generating new keys
|
10
|
-
# by joining the previous key path to the value with a '.'
|
11
|
-
#
|
12
|
-
# hash - The original Hash.
|
13
|
-
# namespace - An optional namespace, default: [].
|
14
|
-
# tree - An optional tree to add values to, default: {}.
|
15
|
-
#
|
16
|
-
# Examples
|
17
|
-
# flatten_hash({da: {session: { login: 'Log ind', logout: 'Log ud' }}})
|
18
|
-
# # => {"da.session.login"=>"Log ind", "da.session.logout"=>"Log ud"}
|
19
|
-
#
|
20
|
-
# Returns the generated Hash.
|
21
|
-
def flatten_hash(hash, namespace = [], tree = {})
|
22
|
-
hash.each do |key, value|
|
23
|
-
child_ns = namespace.dup << key
|
24
|
-
if value.is_a?(Hash)
|
25
|
-
flatten_hash value, child_ns, tree
|
26
|
-
else
|
27
|
-
tree[child_ns.join('.')] = value
|
28
|
-
end
|
29
|
-
end
|
30
|
-
tree
|
31
|
-
end
|
32
|
-
module_function :flatten_hash
|
33
|
-
|
34
|
-
# Public: Converts a flat hash with key path to the value joined
|
35
|
-
# with a '.' to a one level Hash, it's the reverse of flatten_hash
|
36
|
-
#
|
37
|
-
# hash - Hash with keys that represent the path to the value in the new Hash
|
38
|
-
#
|
39
|
-
# Examples
|
40
|
-
# nest_hash({"da.session.login"=>"Log ind", "da.session.logout"=>"Log ud"})
|
41
|
-
# # => {"da"=>{"session"=>{"login"=>"Log ind", "logout"=>"Log ud"}}}
|
42
|
-
#
|
43
|
-
# Returns the generated Hash.
|
44
|
-
def nest_hash(hash)
|
45
|
-
result = {}
|
46
|
-
hash.each do |key, value|
|
47
|
-
begin
|
48
|
-
nest_key result, key, value
|
49
|
-
rescue StandardError
|
50
|
-
raise TransformationError,
|
51
|
-
"Failed to nest key: #{key.inspect} with #{value.inspect}"
|
52
|
-
end
|
53
|
-
end
|
54
|
-
result
|
55
|
-
end
|
56
|
-
module_function :nest_hash
|
57
|
-
|
58
|
-
private
|
59
|
-
|
60
|
-
# Recursively nests point-separated keys from a string in a hash and
|
61
|
-
# assigns the given value to this new hash entry
|
62
|
-
def nest_key(result, key, value)
|
63
|
-
sub_result = result
|
64
|
-
keys = key.split('.')
|
65
|
-
keys.each_with_index do |k, idx|
|
66
|
-
if keys.size - 1 == idx
|
67
|
-
sub_result[k] = value
|
68
|
-
else
|
69
|
-
sub_result = (sub_result[k] ||= {})
|
70
|
-
end
|
71
|
-
end
|
72
|
-
end
|
73
|
-
module_function :nest_key
|
74
|
-
end
|
75
|
-
end
|
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'test_helper'
|
4
|
-
require 'i18n_yaml_editor/transformation'
|
5
|
-
|
6
|
-
class TestTransformation < Minitest::Test
|
7
|
-
I18N_HASH = {
|
8
|
-
'da.session.login' => 'Log ind',
|
9
|
-
'da.session.logout' => 'Log ud',
|
10
|
-
'en.session.login' => 'Log in',
|
11
|
-
'en.session.logout' => 'Log out'
|
12
|
-
}.freeze
|
13
|
-
|
14
|
-
def test_flatten_hash
|
15
|
-
input = {
|
16
|
-
da: {
|
17
|
-
session: { login: 'Log ind', logout: 'Log ud' }
|
18
|
-
},
|
19
|
-
en: {
|
20
|
-
session: { login: 'Log in', logout: 'Log out' }
|
21
|
-
}
|
22
|
-
}
|
23
|
-
|
24
|
-
assert_equal I18N_HASH, Transformation.flatten_hash(input)
|
25
|
-
end
|
26
|
-
|
27
|
-
def test_nest_hash
|
28
|
-
expected = {
|
29
|
-
da: {
|
30
|
-
session: { login: 'Log ind', logout: 'Log ud' }
|
31
|
-
},
|
32
|
-
en: {
|
33
|
-
session: { login: 'Log in', logout: 'Log out' }
|
34
|
-
}
|
35
|
-
}.with_indifferent_access
|
36
|
-
|
37
|
-
assert_equal expected, Transformation.nest_hash(I18N_HASH)
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_nest_hash_transformation_error
|
41
|
-
assert_raises(TransformationError) do
|
42
|
-
Transformation.nest_hash(error: 'value')
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|