i18n-validator 0.0.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.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in i18n-validator.gemspec
4
+ gemspec
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,5 @@
1
+ require 'i18n-validator'
2
+
3
+ I18n::Validator::missing_locales(Dir[File.join(".", "config", "locales", "*")]).each do |key, missing_locales|
4
+ puts "- #{key} is missing in locale#{missing_locales.length == 1 ? "" : "s"} #{missing_locales.join(", ").gsub(/\, ([^\,]*)$/, " and \\1")}"
5
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "i18n-validator/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "i18n-validator"
7
+ s.version = I18n::Validator::VERSION
8
+ s.authors = ["Rene van Lieshout"]
9
+ s.email = ["rene@bluerail.nl"]
10
+ s.homepage = "http://www.bluerail.nl"
11
+ s.summary = %q{I18n completeness validator}
12
+ s.description = %q{Validats your I18n completness}
13
+
14
+ s.rubyforge_project = "i18n-validator"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ s.add_runtime_dependency "i18n"
22
+ s.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,113 @@
1
+ require "i18n"
2
+ require "i18n-validator/version"
3
+
4
+ module I18n
5
+ module Validator
6
+ #
7
+ # Presents a list of missing locale entries
8
+ #
9
+ def self.missing_locales(path)
10
+ I18n.load_path << path
11
+
12
+ # Fetch all keys per locale
13
+ keys_per_locale = Hash[I18n.available_locales.map{ |locale|
14
+ [
15
+ locale,
16
+ I18n.translate('.', :locale => locale).map{ |key, value|
17
+ self.convert_key_value_hash_to_array(key, value)
18
+ }.flatten.sort
19
+ ]
20
+ }]
21
+
22
+ if keys_per_locale.length <= 1
23
+ # there couldn't be any missing locales
24
+ # when we only have 1 locale...
25
+ []
26
+ else
27
+ # Remap Hash to use values as keys
28
+ locales_per_key = self.invert_key_value_hash(keys_per_locale)
29
+ available_locales_length = I18n.available_locales.length
30
+ locales_per_key.reject{ |key, locales|
31
+ locales.length == available_locales_length
32
+ }.sort{ |a,b|
33
+ a[0] <=> b[0]
34
+ }.map{ |key, locales|
35
+ [key, (I18n.available_locales - locales).sort{ |a,b| a.to_s <=> b.to_s }]
36
+ }
37
+ end
38
+ end
39
+
40
+ private
41
+
42
+ #
43
+ # Converts a key-value(s) Hash to a Hash with
44
+ # I18n-alike strings, such as:
45
+ #
46
+ # Input:
47
+ #
48
+ # en:
49
+ # user:
50
+ # edit:
51
+ # title: Edit user details
52
+ # submit_button: Save
53
+ # nl:
54
+ # user:
55
+ # edit:
56
+ # title: Gebruikersgegevens bewerken
57
+ #
58
+ # Output:
59
+ #
60
+ # :en => [
61
+ # "user.edit.title",
62
+ # "user.edit.submit_button"
63
+ # ]
64
+ # :nl => [
65
+ # "user.edit.title"
66
+ # ]
67
+ #
68
+ def self.convert_key_value_hash_to_array(key, value, parent_label = "")
69
+ if value.is_a?(Hash)
70
+ value.map do |subkey, subvalue|
71
+ convert_key_value_hash_to_array(subkey, subvalue, "#{parent_label}#{key}.")
72
+ end
73
+ else
74
+ "#{parent_label}#{key}"
75
+ end
76
+ end
77
+
78
+ #
79
+ # Remaps an Hash to use the key as value and vice versa
80
+ #
81
+ # A value which is available in multiple keys would result
82
+ # in a key with multiple values
83
+ #
84
+ # Example input:
85
+ #
86
+ # :en => [
87
+ # "user.edit.title",
88
+ # "user.edit.submit_button"
89
+ # ]
90
+ # :nl => [
91
+ # "user.edit.title"
92
+ # ]
93
+ #
94
+ # Result:
95
+ #
96
+ # [
97
+ # "user.edit.title" => [:en, :nl],
98
+ # "user.edit.submit_button" => [:en]
99
+ # ]
100
+ #
101
+ def self.invert_key_value_hash(keys_per_locale)
102
+ keys_per_locale.invert.map{ |keys, locale|
103
+ Hash[keys.map{ |key|
104
+ [key, [locale]]
105
+ }]
106
+ }.reduce{ |keys_per_locale_1, keys_per_locale_2|
107
+ keys_per_locale_1.merge!(keys_per_locale_2){ |key, locale_1, locale_2|
108
+ locale_1 + locale_2
109
+ }
110
+ }
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,5 @@
1
+ module I18n
2
+ module Validator
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ de:
2
+ foo:
3
+ bar:
4
+ baz: Baz!
5
+
@@ -0,0 +1,7 @@
1
+ en:
2
+ foo:
3
+ bar:
4
+ baz: Baz!
5
+ hello:
6
+ world: Hello World!
7
+
@@ -0,0 +1,8 @@
1
+ nl:
2
+ foo:
3
+ bar:
4
+ baz: Baz!
5
+ hello:
6
+ world: Hello World!
7
+ kitty: Hello Kitty
8
+
@@ -0,0 +1,13 @@
1
+ require 'spec_helper'
2
+ require 'pp'
3
+
4
+ describe I18n::Validator do
5
+ it "should find missing locales" do
6
+ missing_locales = I18n::Validator::missing_locales(Dir[File.join(File.dirname(__FILE__), "fixtures", "locales", "*")])
7
+
8
+ missing_locales.should eql([
9
+ ["hello.kitty", [:de, :en]],
10
+ ["hello.world", [:de]]
11
+ ])
12
+ end
13
+ end
@@ -0,0 +1,8 @@
1
+ require 'rubygems'
2
+ require 'bundler/setup'
3
+
4
+ require 'i18n-validator'
5
+
6
+ RSpec.configure do |config|
7
+
8
+ end
metadata ADDED
@@ -0,0 +1,108 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: i18n-validator
3
+ version: !ruby/object:Gem::Version
4
+ hash: 29
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 0
9
+ - 1
10
+ version: 0.0.1
11
+ platform: ruby
12
+ authors:
13
+ - Rene van Lieshout
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-03-27 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: i18n
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ hash: 3
29
+ segments:
30
+ - 0
31
+ version: "0"
32
+ type: :runtime
33
+ version_requirements: *id001
34
+ - !ruby/object:Gem::Dependency
35
+ name: rspec
36
+ prerelease: false
37
+ requirement: &id002 !ruby/object:Gem::Requirement
38
+ none: false
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ hash: 3
43
+ segments:
44
+ - 0
45
+ version: "0"
46
+ type: :development
47
+ version_requirements: *id002
48
+ description: Validats your I18n completness
49
+ email:
50
+ - rene@bluerail.nl
51
+ executables:
52
+ - i18n-validate
53
+ extensions: []
54
+
55
+ extra_rdoc_files: []
56
+
57
+ files:
58
+ - .gitignore
59
+ - Gemfile
60
+ - Rakefile
61
+ - bin/i18n-validate
62
+ - i18n-validator.gemspec
63
+ - lib/i18n-validator.rb
64
+ - lib/i18n-validator/version.rb
65
+ - spec/fixtures/locales/de.yml
66
+ - spec/fixtures/locales/en.yml
67
+ - spec/fixtures/locales/nl.yml
68
+ - spec/i18n_validator_spec.rb
69
+ - spec/spec_helper.rb
70
+ homepage: http://www.bluerail.nl
71
+ licenses: []
72
+
73
+ post_install_message:
74
+ rdoc_options: []
75
+
76
+ require_paths:
77
+ - lib
78
+ required_ruby_version: !ruby/object:Gem::Requirement
79
+ none: false
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ hash: 3
84
+ segments:
85
+ - 0
86
+ version: "0"
87
+ required_rubygems_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ requirements: []
97
+
98
+ rubyforge_project: i18n-validator
99
+ rubygems_version: 1.8.11
100
+ signing_key:
101
+ specification_version: 3
102
+ summary: I18n completeness validator
103
+ test_files:
104
+ - spec/fixtures/locales/de.yml
105
+ - spec/fixtures/locales/en.yml
106
+ - spec/fixtures/locales/nl.yml
107
+ - spec/i18n_validator_spec.rb
108
+ - spec/spec_helper.rb