i18nema19 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,79 @@
1
+ require 'yaml' if RUBY_VERSION >= "2.0" # otherwise syck asplodes
2
+ require 'syck'
3
+ require 'i18n'
4
+ require File.dirname(__FILE__) + '/i18nema/core_ext/hash'
5
+ require File.dirname(__FILE__) + '/i18nema/i18nema'
6
+
7
+ module I18nema
8
+ module CoreMethods
9
+ RESERVED_KEY_MAP = Hash[I18n::RESERVED_KEYS.map{|k|[k,true]}]
10
+
11
+ def translate(locale, key, options = {})
12
+ raise I18n::InvalidLocale.new(locale) unless locale
13
+ entry = key && lookup(locale, key, options[:scope], options)
14
+
15
+ if options.empty?
16
+ entry = resolve(locale, key, entry, options)
17
+ else
18
+ count, default = options.values_at(:count, :default)
19
+ # significant speedup over Hash#except
20
+ values = options.reject { |key, value| RESERVED_KEY_MAP.key?(key) }
21
+ entry = entry.nil? && default ?
22
+ default(locale, key, default, options) : resolve(locale, key, entry, options)
23
+ end
24
+
25
+ throw(:exception, I18n::MissingTranslation.new(locale, key, options)) if entry.nil?
26
+ # no need to dup, since I18nema gives us a new string
27
+
28
+ entry = pluralize(locale, entry, count) if count
29
+ entry = interpolate(locale, entry, values) if values
30
+ entry
31
+ end
32
+ end
33
+
34
+ class Backend
35
+ include I18n::Backend::Base
36
+ include CoreMethods # defined in a module so that other modules (e.g. I18n::Backend::Fallbacks) can override them
37
+
38
+ def store_translations(locale, data, options = {})
39
+ # TODO: make this moar awesome
40
+ @initialized = true
41
+ load_yml_string({locale => data}.deep_stringify_keys.to_yaml)
42
+ end
43
+
44
+ def init_translations
45
+ load_translations
46
+ @initialized = true
47
+ end
48
+
49
+ protected
50
+ def load_file(filename)
51
+ type = File.extname(filename).tr('.', '').downcase
52
+ raise I18n::UnknownFileType.new(type, filename) unless type == "yml"
53
+ load_yml(filename)
54
+ end
55
+
56
+ def load_yml(filename)
57
+ load_yml_string File.read(filename)
58
+ end
59
+
60
+ def initialized?
61
+ @initialized
62
+ end
63
+
64
+ def lookup(locale, key, scope = [], options = {})
65
+ init_translations unless initialized?
66
+ keys = normalize_keys(locale, key, scope, options[:separator])
67
+ direct_lookup(*keys)
68
+ end
69
+
70
+ def normalize_keys(locale, key, scope, separator = nil)
71
+ separator ||= I18n.default_separator
72
+
73
+ keys = [locale.to_s]
74
+ keys.concat normalize_key(scope, separator) if scope && scope.size > 0
75
+ keys.concat normalize_key(key, separator)
76
+ keys
77
+ end
78
+ end
79
+ end
@@ -0,0 +1,8 @@
1
+ class Hash
2
+ def deep_stringify_keys
3
+ Hash[map{ |key, value|
4
+ value = value.deep_stringify_keys if value.is_a?(Hash)
5
+ [key.to_s, value]
6
+ }]
7
+ end unless Hash.method_defined?(:deep_stringify_keys)
8
+ end
@@ -0,0 +1 @@
1
+ require 'i18nema'
@@ -0,0 +1,5 @@
1
+ require 'bundler/setup'
2
+ Bundler.require(:default)
3
+
4
+ require 'test/unit'
5
+ require 'i18nema'
@@ -0,0 +1,97 @@
1
+ require 'helper'
2
+ require 'yaml'
3
+
4
+ class I18nemaTest < Test::Unit::TestCase
5
+ def setup
6
+ @data = {
7
+ foo: {
8
+ bar: "lol"
9
+ },
10
+ baz: %w{
11
+ asdf
12
+ qwerty
13
+ },
14
+ stuff: [
15
+ true,
16
+ true,
17
+ false,
18
+ nil,
19
+ 1,
20
+ 1.1,
21
+ :foo
22
+ ]
23
+ }
24
+ @backend = I18nema::Backend.new
25
+ @backend.store_translations :en, @data
26
+ end
27
+
28
+ def test_yaml_parity
29
+ assert_equal({en: @data}, @backend.direct_lookup)
30
+ end
31
+
32
+ def test_scoping
33
+ assert_equal({bar: "lol"},
34
+ @backend.direct_lookup("en", "foo"))
35
+ assert_equal "lol",
36
+ @backend.direct_lookup("en", "foo", "bar")
37
+ assert_equal nil,
38
+ @backend.direct_lookup("poo")
39
+ end
40
+
41
+ def test_merging
42
+ @backend.store_translations :en, foo: "replaced!", wat: "added!"
43
+ assert_equal "replaced!",
44
+ @backend.direct_lookup("en", "foo")
45
+ assert_equal ["asdf", "qwerty"],
46
+ @backend.direct_lookup("en", "baz")
47
+ assert_equal "added!",
48
+ @backend.direct_lookup("en", "wat")
49
+ end
50
+
51
+ def test_reload
52
+ @backend.reload!
53
+ assert_equal({}, @backend.direct_lookup)
54
+ end
55
+
56
+ def test_available_locales
57
+ @backend.store_translations :es, foo: "hola"
58
+ assert_equal ['en', 'es'],
59
+ @backend.available_locales.map(&:to_s).sort
60
+ end
61
+
62
+ def test_invalid_yml
63
+ backend = I18nema::Backend.new
64
+
65
+ exception = assert_raise(I18nema::Backend::LoadError) {
66
+ backend.load_yml_string("string")
67
+ }
68
+ assert_equal("root yml node is not a hash", exception.message)
69
+ assert_equal({}, backend.direct_lookup)
70
+
71
+ exception = assert_raise(I18nema::Backend::LoadError) {
72
+ backend.load_yml_string("en:\n foo: \"lol\"\n\tbar: notabs!")
73
+ }
74
+ assert_match(/syntax error/, exception.message)
75
+ assert_equal({}, backend.direct_lookup)
76
+
77
+ exception = assert_raise(I18nema::Backend::LoadError) {
78
+ backend.load_yml_string("en:\n &a [*a]")
79
+ }
80
+ assert_match(/bad anchor `a'/, exception.message)
81
+ assert_equal({}, backend.direct_lookup)
82
+ end
83
+
84
+ def test_normalize_key
85
+ backend = I18nema::Backend.new
86
+ assert_equal %w{asdf},
87
+ backend.normalize_key("asdf", ".")
88
+ assert_equal %w{asdf asdf},
89
+ backend.normalize_key("asdf.asdf", ".")
90
+ assert_equal %w{asdf.asdf},
91
+ backend.normalize_key("asdf.asdf", ",")
92
+ assert_equal %w{asdf asdf},
93
+ backend.normalize_key("asdf...asdf", ".")
94
+ assert_equal %w{asdf asdf asdf},
95
+ backend.normalize_key(%w{asdf asdf.asdf}, ".")
96
+ end
97
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: i18nema19
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.8
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jon Jensen
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-01-16 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: i18n
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0.5'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0.5'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rake-compiler
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0.8'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0.8'
46
+ description: drop-in replacement for I18n::Backend::Simple for faster lookups and
47
+ quicker gc runs. translations are stored outside of the ruby heap
48
+ email: jon@instructure.com
49
+ executables: []
50
+ extensions:
51
+ - ext/i18nema/extconf.rb
52
+ extra_rdoc_files: []
53
+ files:
54
+ - Rakefile
55
+ - README.md
56
+ - ext/i18nema/i18nema.c
57
+ - ext/i18nema/vendor/syck.h
58
+ - ext/i18nema/vendor/uthash.h
59
+ - ext/i18nema/extconf.rb
60
+ - lib/i18nema/core_ext/hash.rb
61
+ - lib/i18nema.rb
62
+ - lib/i18nema19.rb
63
+ - test/helper.rb
64
+ - test/i18nema_test.rb
65
+ homepage: http://github.com/instructure/i18nema
66
+ licenses: []
67
+ post_install_message:
68
+ rdoc_options: []
69
+ require_paths:
70
+ - lib
71
+ required_ruby_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: 1.9.3
77
+ required_rubygems_version: !ruby/object:Gem::Requirement
78
+ none: false
79
+ requirements:
80
+ - - ! '>='
81
+ - !ruby/object:Gem::Version
82
+ version: 1.3.5
83
+ requirements: []
84
+ rubyforge_project:
85
+ rubygems_version: 1.8.25
86
+ signing_key:
87
+ specification_version: 3
88
+ summary: fast i18n backend that doesn't stop up the garbage collector
89
+ test_files: []
90
+ has_rdoc: