i18n 0.3.2 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of i18n might be problematic. Click here for more details.
- data/Rakefile +3 -0
- data/lib/i18n.rb +6 -5
- data/lib/i18n/backend.rb +13 -11
- data/lib/i18n/backend/active_record.rb +1 -1
- data/lib/i18n/backend/active_record/missing.rb +9 -6
- data/lib/i18n/backend/active_record/translation.rb +2 -1
- data/lib/i18n/backend/base.rb +22 -17
- data/lib/i18n/backend/chain.rb +1 -1
- data/lib/i18n/backend/fallbacks.rb +2 -1
- data/lib/i18n/backend/fast.rb +68 -0
- data/lib/i18n/backend/helpers.rb +34 -7
- data/lib/i18n/backend/interpolation_compiler.rb +119 -0
- data/lib/i18n/exceptions.rb +2 -2
- data/lib/i18n/version.rb +3 -0
- data/test/api/link.rb +39 -24
- data/test/api/lookup.rb +7 -3
- data/test/cases/api/all_features_test.rb +3 -0
- data/test/cases/api/cascade_test.rb +31 -0
- data/test/cases/api/fast_test.rb +31 -0
- data/test/cases/backend/active_record/missing_test.rb +1 -1
- data/test/cases/backend/fast_test.rb +50 -0
- data/test/cases/backend/helpers_test.rb +2 -2
- data/test/cases/backend/interpolation_compiler_test.rb +107 -0
- data/test/cases/backend/metadata_test.rb +1 -1
- data/test/cases/i18n_test.rb +5 -0
- data/test/test_helper.rb +5 -4
- metadata +13 -3
- data/VERSION +0 -1
data/Rakefile
CHANGED
@@ -4,10 +4,13 @@ task :test do
|
|
4
4
|
ruby "test/all.rb"
|
5
5
|
end
|
6
6
|
|
7
|
+
require File.expand_path("lib/i18n/version", File.dirname(__FILE__))
|
8
|
+
|
7
9
|
begin
|
8
10
|
require 'jeweler'
|
9
11
|
Jeweler::Tasks.new do |s|
|
10
12
|
s.name = "i18n"
|
13
|
+
s.version = I18n::VERSION
|
11
14
|
s.rubyforge_project = "i18n"
|
12
15
|
s.summary = "New wave Internationalization support for Ruby"
|
13
16
|
s.email = "rails-i18n@googlegroups.com"
|
data/lib/i18n.rb
CHANGED
@@ -201,11 +201,11 @@ module I18n
|
|
201
201
|
# always return the same translations/values per unique combination of argument
|
202
202
|
# values.
|
203
203
|
def translate(*args)
|
204
|
-
options = args.last.is_a?(Hash)
|
204
|
+
options = args.pop if args.last.is_a?(Hash)
|
205
205
|
key = args.shift
|
206
|
-
locale = options.delete(:locale) || I18n.locale
|
207
|
-
raises = options.delete(:raise)
|
208
|
-
backend.translate(locale, key, options)
|
206
|
+
locale = options && options.delete(:locale) || I18n.locale
|
207
|
+
raises = options && options.delete(:raise)
|
208
|
+
backend.translate(locale, key, options || {})
|
209
209
|
rescue I18n::ArgumentError => exception
|
210
210
|
raise exception if raises
|
211
211
|
handle_exception(exception, locale, key, options)
|
@@ -270,7 +270,8 @@ module I18n
|
|
270
270
|
def normalize_translation_keys(locale, key, scope, separator = nil)
|
271
271
|
keys = [locale] + Array(scope) + Array(key)
|
272
272
|
keys = keys.map { |k| k.to_s.split(separator || I18n.default_separator) }
|
273
|
-
keys.flatten
|
273
|
+
keys = keys.flatten - ['']
|
274
|
+
keys.map { |k| k.to_sym }
|
274
275
|
end
|
275
276
|
end
|
276
277
|
end
|
data/lib/i18n/backend.rb
CHANGED
@@ -1,15 +1,17 @@
|
|
1
1
|
module I18n
|
2
2
|
module Backend
|
3
|
-
autoload :ActiveRecord,
|
4
|
-
autoload :Base,
|
5
|
-
autoload :Cache,
|
6
|
-
autoload :Cascade,
|
7
|
-
autoload :Chain,
|
8
|
-
autoload :Fallbacks,
|
9
|
-
autoload :
|
10
|
-
autoload :
|
11
|
-
autoload :
|
12
|
-
autoload :
|
13
|
-
autoload :
|
3
|
+
autoload :ActiveRecord, 'i18n/backend/active_record'
|
4
|
+
autoload :Base, 'i18n/backend/base'
|
5
|
+
autoload :Cache, 'i18n/backend/cache'
|
6
|
+
autoload :Cascade, 'i18n/backend/cascade'
|
7
|
+
autoload :Chain, 'i18n/backend/chain'
|
8
|
+
autoload :Fallbacks, 'i18n/backend/fallbacks'
|
9
|
+
autoload :Fast, 'i18n/backend/fast'
|
10
|
+
autoload :Gettext, 'i18n/backend/gettext'
|
11
|
+
autoload :Helpers, 'i18n/backend/helpers'
|
12
|
+
autoload :InterpolationCompiler, 'i18n/backend/interpolation_compiler'
|
13
|
+
autoload :Metadata, 'i18n/backend/metadata'
|
14
|
+
autoload :Pluralization, 'i18n/backend/pluralization'
|
15
|
+
autoload :Simple, 'i18n/backend/simple'
|
14
16
|
end
|
15
17
|
end
|
@@ -24,7 +24,7 @@ module I18n
|
|
24
24
|
separator = options[:separator] || I18n.default_separator
|
25
25
|
wind_keys(data, separator).each do |key, v|
|
26
26
|
Translation.locale(locale).lookup(expand_keys(key, separator), separator).delete_all
|
27
|
-
Translation.create(:locale => locale.to_s, :key => key, :value => v)
|
27
|
+
Translation.create(:locale => locale.to_s, :key => key.to_s, :value => v)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
|
@@ -11,19 +11,21 @@
|
|
11
11
|
# I18n.backend = I18nChainBackend.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)
|
12
12
|
#
|
13
13
|
# Stub records for pluralizations will also be created for each key defined
|
14
|
-
# in i18n.
|
14
|
+
# in i18n.plural.keys.
|
15
15
|
#
|
16
16
|
# For example:
|
17
17
|
#
|
18
18
|
# # en.yml
|
19
19
|
# en:
|
20
20
|
# i18n:
|
21
|
-
#
|
21
|
+
# plural:
|
22
|
+
# keys: [:zero, :one, :other]
|
22
23
|
#
|
23
24
|
# # pl.yml
|
24
25
|
# pl:
|
25
26
|
# i18n:
|
26
|
-
#
|
27
|
+
# plural:
|
28
|
+
# keys: [:zero, :one, :few, :other]
|
27
29
|
#
|
28
30
|
# It will also persist interpolation keys in Translation#interpolations so
|
29
31
|
# translators will be able to review and use them.
|
@@ -34,13 +36,14 @@ module I18n
|
|
34
36
|
def store_default_translations(locale, key, options = {})
|
35
37
|
count, scope, default, separator = options.values_at(:count, *Base::RESERVED_KEYS)
|
36
38
|
separator ||= I18n.default_separator
|
39
|
+
|
37
40
|
keys = I18n.send(:normalize_translation_keys, locale, key, scope, separator)[1..-1]
|
38
41
|
key = keys.join(separator || I18n.default_separator)
|
39
42
|
|
40
43
|
unless ActiveRecord::Translation.locale(locale).lookup(key, separator).exists?
|
41
44
|
interpolations = options.reject { |name, value| Base::RESERVED_KEYS.include?(name) }.keys
|
42
|
-
keys = count ? I18n.t('i18n.
|
43
|
-
keys.each { |key| store_default_translation(locale, key, interpolations) }
|
45
|
+
keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(separator) } : [key]
|
46
|
+
keys.each { |key| store_default_translation(locale, key, interpolations) }
|
44
47
|
end
|
45
48
|
end
|
46
49
|
|
@@ -49,7 +52,7 @@ module I18n
|
|
49
52
|
translation.interpolations = interpolations
|
50
53
|
translation.save
|
51
54
|
end
|
52
|
-
|
55
|
+
|
53
56
|
def translate(locale, key, options = {})
|
54
57
|
super
|
55
58
|
|
data/lib/i18n/backend/base.rb
CHANGED
@@ -26,18 +26,24 @@ module I18n
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def translate(locale, key, options = {})
|
29
|
-
raise InvalidLocale.new(locale)
|
29
|
+
raise InvalidLocale.new(locale) unless locale
|
30
30
|
return key.map { |k| translate(locale, k, options) } if key.is_a?(Array)
|
31
31
|
|
32
|
-
|
33
|
-
|
32
|
+
if options.empty?
|
33
|
+
entry = resolve(locale, key, lookup(locale, key), options)
|
34
|
+
raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
|
35
|
+
else
|
36
|
+
count, scope, default, separator = options.values_at(:count, :scope, :default, :separator)
|
37
|
+
values = options.reject { |name, value| RESERVED_KEYS.include?(name) }
|
34
38
|
|
35
|
-
|
36
|
-
|
39
|
+
entry = lookup(locale, key, scope, separator)
|
40
|
+
entry = entry.nil? && default ? default(locale, key, default, options) : resolve(locale, key, entry, options)
|
41
|
+
raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
|
42
|
+
|
43
|
+
entry = pluralize(locale, entry, count) if count
|
44
|
+
entry = interpolate(locale, entry, values) if values
|
45
|
+
end
|
37
46
|
|
38
|
-
raise(I18n::MissingTranslationData.new(locale, key, options)) if entry.nil?
|
39
|
-
entry = pluralize(locale, entry, count)
|
40
|
-
entry = interpolate(locale, entry, values)
|
41
47
|
entry
|
42
48
|
end
|
43
49
|
|
@@ -108,11 +114,10 @@ module I18n
|
|
108
114
|
keys = I18n.send(:normalize_translation_keys, locale, key, scope, separator)
|
109
115
|
keys.inject(translations) do |result, key|
|
110
116
|
key = key.to_sym
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
end
|
117
|
+
return nil unless result.is_a?(Hash) && result.has_key?(key)
|
118
|
+
result = result[key]
|
119
|
+
result = resolve(locale, key, result, :separator => separator) if result.is_a?(Symbol)
|
120
|
+
result
|
116
121
|
end
|
117
122
|
end
|
118
123
|
|
@@ -124,8 +129,8 @@ module I18n
|
|
124
129
|
options = options.dup.reject { |key, value| key == :default }
|
125
130
|
case subject
|
126
131
|
when Array
|
127
|
-
subject.each do |
|
128
|
-
result = resolve(locale, object,
|
132
|
+
subject.each do |item|
|
133
|
+
result = resolve(locale, object, item, options) and return result
|
129
134
|
end and nil
|
130
135
|
else
|
131
136
|
resolve(locale, object, subject, options)
|
@@ -136,10 +141,10 @@ module I18n
|
|
136
141
|
# If the given subject is a Symbol, it will be translated with the
|
137
142
|
# given options. If it is a Proc then it will be evaluated. All other
|
138
143
|
# subjects will be returned directly.
|
139
|
-
def resolve(locale, object, subject, options =
|
144
|
+
def resolve(locale, object, subject, options = nil)
|
140
145
|
case subject
|
141
146
|
when Symbol
|
142
|
-
I18n.translate(subject, options.merge(:locale => locale, :raise => true))
|
147
|
+
I18n.translate(subject, (options || {}).merge(:locale => locale, :raise => true))
|
143
148
|
when Proc
|
144
149
|
resolve(locale, object, subject.call(object, options), options = {})
|
145
150
|
else
|
data/lib/i18n/backend/chain.rb
CHANGED
@@ -40,7 +40,8 @@ module I18n
|
|
40
40
|
def translate(locale, key, options = {})
|
41
41
|
I18n.fallbacks[locale].each do |fallback|
|
42
42
|
begin
|
43
|
-
result = super(fallback, key, options)
|
43
|
+
result = super(fallback, key, options)
|
44
|
+
return result unless result.nil?
|
44
45
|
rescue I18n::MissingTranslationData
|
45
46
|
end
|
46
47
|
end
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# The Fast module contains optimizations that can tremendously speed up the
|
4
|
+
# lookup process on the Simple backend. It works by flattening the nested
|
5
|
+
# translation hash to a flat hash (e.g. { :a => { :b => 'c' } } becomes
|
6
|
+
# { :'a.b' => 'c' }).
|
7
|
+
#
|
8
|
+
# To enable these optimizations you can simply include the Fast module to
|
9
|
+
# the Simple backend:
|
10
|
+
#
|
11
|
+
# I18n::Backend::Simple.send(:include, I18n::Backend::Fast)
|
12
|
+
module I18n
|
13
|
+
module Backend
|
14
|
+
module Fast
|
15
|
+
SEPARATOR_ESCAPE_CHAR = "\001"
|
16
|
+
|
17
|
+
def reset_flattened_translations!
|
18
|
+
@flattened_translations = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def flattened_translations
|
22
|
+
@flattened_translations ||= flatten_translations(translations)
|
23
|
+
end
|
24
|
+
|
25
|
+
def merge_translations(locale, data)
|
26
|
+
super
|
27
|
+
reset_flattened_translations!
|
28
|
+
end
|
29
|
+
|
30
|
+
def init_translations
|
31
|
+
super
|
32
|
+
reset_flattened_translations!
|
33
|
+
end
|
34
|
+
|
35
|
+
protected
|
36
|
+
# flatten_hash({:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}})
|
37
|
+
# # => {:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"}
|
38
|
+
def flatten_hash(h, nested_stack = [], flattened_h = {}, orig_h=h)
|
39
|
+
wind_keys(h, nil, true)
|
40
|
+
end
|
41
|
+
|
42
|
+
def flatten_translations(translations)
|
43
|
+
# don't flatten locale roots
|
44
|
+
translations.inject({}) do |flattened_h, (locale_name, locale_translations)|
|
45
|
+
flattened_h[locale_name] = flatten_hash(locale_translations)
|
46
|
+
flattened_h
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def lookup(locale, key, scope = nil, separator = nil)
|
51
|
+
return unless key
|
52
|
+
init_translations unless initialized?
|
53
|
+
|
54
|
+
if separator && I18n.default_separator != separator
|
55
|
+
key = cleanup_non_standard_separator(key, separator)
|
56
|
+
scope = Array(scope).map{|k| cleanup_non_standard_separator(k, separator)} if scope
|
57
|
+
end
|
58
|
+
|
59
|
+
key = (Array(scope) + [key]).join(I18n.default_separator) if scope
|
60
|
+
flattened_translations[locale.to_sym][key.to_sym]
|
61
|
+
end
|
62
|
+
|
63
|
+
def cleanup_non_standard_separator(key, user_separator)
|
64
|
+
escape_default_separator(key).tr(user_separator, I18n.default_separator)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
data/lib/i18n/backend/helpers.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
module I18n
|
2
2
|
module Backend
|
3
3
|
module Helpers
|
4
|
+
SEPARATOR_ESCAPE_CHAR = "\001"
|
5
|
+
|
4
6
|
# Return a new hash with all keys and nested keys converted to symbols.
|
5
7
|
def deep_symbolize_keys(hash)
|
6
8
|
hash.inject({}) { |result, (key, value)|
|
@@ -13,16 +15,41 @@ module I18n
|
|
13
15
|
# Flatten keys for nested Hashes by chaining up keys using the separator
|
14
16
|
# >> { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}.wind
|
15
17
|
# => { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
|
16
|
-
def wind_keys(hash, separator =
|
17
|
-
|
18
|
-
|
19
|
-
|
18
|
+
def wind_keys(hash, separator = nil, subtree = false, prev_key = nil, result = {}, orig_hash=hash)
|
19
|
+
separator ||= I18n.default_separator
|
20
|
+
|
21
|
+
hash.each_pair do |key, value|
|
22
|
+
key = escape_default_separator(key, separator)
|
23
|
+
curr_key = [prev_key, key].compact.join(separator).to_sym
|
24
|
+
|
25
|
+
if value.is_a?(Symbol)
|
26
|
+
value = hash_lookup(orig_hash, value, separator) ||
|
27
|
+
hash_lookup(hash, value, separator) || value
|
28
|
+
end
|
29
|
+
|
20
30
|
if value.is_a?(Hash)
|
21
|
-
|
31
|
+
result[curr_key] = value if subtree
|
32
|
+
wind_keys(value, separator, subtree, curr_key, result, orig_hash)
|
22
33
|
else
|
23
34
|
result[curr_key] = value
|
24
35
|
end
|
25
|
-
|
36
|
+
end
|
37
|
+
|
38
|
+
result
|
39
|
+
end
|
40
|
+
|
41
|
+
def escape_default_separator(key, separator=nil)
|
42
|
+
key.to_s.tr(separator || I18n.default_separator, SEPARATOR_ESCAPE_CHAR)
|
43
|
+
end
|
44
|
+
|
45
|
+
def hash_lookup(hash, keys, separator = ".")
|
46
|
+
keys.to_s.split(separator).inject(hash) do |result, key|
|
47
|
+
key = key.to_sym
|
48
|
+
if result.respond_to?(:has_key?) and result.has_key?(key)
|
49
|
+
result[key]
|
50
|
+
else
|
51
|
+
return nil
|
52
|
+
end
|
26
53
|
end
|
27
54
|
end
|
28
55
|
|
@@ -32,7 +59,7 @@ module I18n
|
|
32
59
|
def unwind_keys(hash, separator = ".")
|
33
60
|
result = {}
|
34
61
|
hash.each do |key, value|
|
35
|
-
keys = key.split(separator)
|
62
|
+
keys = key.to_s.split(separator)
|
36
63
|
curr = result
|
37
64
|
curr = curr[keys.shift] ||= {} while keys.size > 1
|
38
65
|
curr[keys.shift] = value
|
@@ -0,0 +1,119 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
# The InterpolationCompiler module contains optimizations that can tremendously
|
4
|
+
# speed up the interpolation process on the Simple backend.
|
5
|
+
#
|
6
|
+
# It works by defining a pre-compiled method on stored translation Strings that
|
7
|
+
# already bring all the knowledge about contained interpolation variables etc.
|
8
|
+
# so that the actual recurring interpolation will be very fast.
|
9
|
+
#
|
10
|
+
# To enable pre-compiled interpolations you can simply include the
|
11
|
+
# InterpolationCompiler module to the Simple backend:
|
12
|
+
#
|
13
|
+
# I18n::Backend::Simple.send(:include, I18n::Backend::InterpolationCompiler)
|
14
|
+
module I18n
|
15
|
+
module Backend
|
16
|
+
module InterpolationCompiler
|
17
|
+
module Compiler
|
18
|
+
extend self
|
19
|
+
|
20
|
+
TOKENIZER = /(\\\{\{[^\}]+\}\}|\{\{[^\}]+\}\})/
|
21
|
+
INTERPOLATION_SYNTAX_PATTERN = /(\\)?(\{\{([^\}]+)\}\})/
|
22
|
+
|
23
|
+
def compile_if_an_interpolation(string)
|
24
|
+
if interpolated_str?(string)
|
25
|
+
string.instance_eval <<-RUBY_EVAL, __FILE__, __LINE__
|
26
|
+
def i18n_interpolate(v = {})
|
27
|
+
"#{compiled_interpolation_body(string)}"
|
28
|
+
end
|
29
|
+
RUBY_EVAL
|
30
|
+
end
|
31
|
+
|
32
|
+
string
|
33
|
+
end
|
34
|
+
|
35
|
+
def interpolated_str?(str)
|
36
|
+
str.kind_of?(String) && str =~ INTERPOLATION_SYNTAX_PATTERN
|
37
|
+
end
|
38
|
+
|
39
|
+
protected
|
40
|
+
# tokenize("foo {{bar}} baz \\{{buz}}") # => ["foo ", "{{bar}}", " baz ", "\\{{buz}}"]
|
41
|
+
def tokenize(str)
|
42
|
+
str.split(TOKENIZER)
|
43
|
+
end
|
44
|
+
|
45
|
+
def compiled_interpolation_body(str)
|
46
|
+
tokenize(str).map do |token|
|
47
|
+
(matchdata = token.match(INTERPOLATION_SYNTAX_PATTERN)) ? handle_interpolation_token(token, matchdata) : escape_plain_str(token)
|
48
|
+
end.join
|
49
|
+
end
|
50
|
+
|
51
|
+
def handle_interpolation_token(interpolation, matchdata)
|
52
|
+
escaped, pattern, key = matchdata.values_at(1, 2, 3)
|
53
|
+
escaped ? pattern : compile_interpolation_token(key.to_sym)
|
54
|
+
end
|
55
|
+
|
56
|
+
def compile_interpolation_token(key)
|
57
|
+
"\#{#{interpolate_or_raise_missing(key)}}"
|
58
|
+
end
|
59
|
+
|
60
|
+
def interpolate_or_raise_missing(key)
|
61
|
+
escaped_key = escape_key_sym(key)
|
62
|
+
Base::RESERVED_KEYS.include?(key) ? reserved_key(escaped_key) : interpolate_key(escaped_key)
|
63
|
+
end
|
64
|
+
|
65
|
+
def interpolate_key(key)
|
66
|
+
[direct_key(key), nil_key(key), missing_key(key)].join('||')
|
67
|
+
end
|
68
|
+
|
69
|
+
def direct_key(key)
|
70
|
+
"((t = v[#{key}]) && t.respond_to?(:call) ? t.call : t)"
|
71
|
+
end
|
72
|
+
|
73
|
+
def nil_key(key)
|
74
|
+
"(v.has_key?(#{key}) && '')"
|
75
|
+
end
|
76
|
+
|
77
|
+
def missing_key(key)
|
78
|
+
"raise(MissingInterpolationArgument.new(#{key}, self))"
|
79
|
+
end
|
80
|
+
|
81
|
+
def reserved_key(key)
|
82
|
+
"raise(ReservedInterpolationKey.new(#{key}, self))"
|
83
|
+
end
|
84
|
+
|
85
|
+
def escape_plain_str(str)
|
86
|
+
str.gsub(/"|\\|#/) {|x| "\\#{x}"}
|
87
|
+
end
|
88
|
+
|
89
|
+
def escape_key_sym(key)
|
90
|
+
# rely on Ruby to do all the hard work :)
|
91
|
+
key.to_sym.inspect
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def interpolate(locale, string, values)
|
96
|
+
if string.respond_to?(:i18n_interpolate)
|
97
|
+
string.i18n_interpolate(values)
|
98
|
+
elsif values
|
99
|
+
super
|
100
|
+
else
|
101
|
+
string
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
def merge_translations(locale, data)
|
106
|
+
compile_all_strings_in(data)
|
107
|
+
super
|
108
|
+
end
|
109
|
+
|
110
|
+
protected
|
111
|
+
def compile_all_strings_in(data)
|
112
|
+
data.each_value do |value|
|
113
|
+
Compiler.compile_if_an_interpolation(value)
|
114
|
+
compile_all_strings_in(value) if value.kind_of?(Hash)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
data/lib/i18n/exceptions.rb
CHANGED
@@ -19,8 +19,8 @@ module I18n
|
|
19
19
|
|
20
20
|
class MissingTranslationData < ArgumentError
|
21
21
|
attr_reader :locale, :key, :options
|
22
|
-
def initialize(locale, key,
|
23
|
-
@key, @locale, @options = key, locale,
|
22
|
+
def initialize(locale, key, opts = nil)
|
23
|
+
@key, @locale, @options = key, locale, opts || {}
|
24
24
|
keys = I18n.send(:normalize_translation_keys, locale, key, options[:scope])
|
25
25
|
keys << 'no key' if keys.size < 2
|
26
26
|
super "translation missing: #{keys.join(', ')}"
|
data/lib/i18n/version.rb
ADDED
data/test/api/link.rb
CHANGED
@@ -3,38 +3,53 @@
|
|
3
3
|
module Tests
|
4
4
|
module Api
|
5
5
|
module Link
|
6
|
-
define_method "test linked lookup:
|
7
|
-
|
8
|
-
|
6
|
+
define_method "test linked lookup: if a key resolves to a symbol it looks up the symbol" do
|
7
|
+
I18n.backend.store_translations 'en', {
|
8
|
+
:link => :linked,
|
9
|
+
:linked => 'linked'
|
10
|
+
}
|
11
|
+
assert_equal 'linked', I18n.backend.translate('en', :link)
|
9
12
|
end
|
10
13
|
|
11
|
-
define_method "test linked lookup:
|
12
|
-
|
13
|
-
|
14
|
+
define_method "test linked lookup: if a key resolves to a dot-separated symbol it looks up the symbol" do
|
15
|
+
I18n.backend.store_translations 'en', {
|
16
|
+
:link => :"foo.linked",
|
17
|
+
:foo => { :linked => 'linked' }
|
18
|
+
}
|
19
|
+
assert_equal('linked', I18n.backend.translate('en', :link))
|
14
20
|
end
|
15
|
-
|
16
|
-
define_method "test linked lookup:
|
17
|
-
|
18
|
-
|
21
|
+
|
22
|
+
define_method "test linked lookup: if a dot-separated key resolves to a symbol it looks up the symbol" do
|
23
|
+
I18n.backend.store_translations 'en', {
|
24
|
+
:foo => { :link => :linked },
|
25
|
+
:linked => 'linked'
|
26
|
+
}
|
27
|
+
assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
|
19
28
|
end
|
20
29
|
|
21
|
-
define_method "test linked lookup:
|
22
|
-
|
23
|
-
|
30
|
+
define_method "test linked lookup: if a dot-separated key resolves to a dot-separated symbol it looks up the symbol" do
|
31
|
+
I18n.backend.store_translations 'en', {
|
32
|
+
:foo => { :link => :"bar.linked" },
|
33
|
+
:bar => { :linked => 'linked' }
|
34
|
+
}
|
35
|
+
assert_equal('linked', I18n.backend.translate('en', :'foo.link'))
|
24
36
|
end
|
25
37
|
|
26
|
-
|
38
|
+
define_method "test linked lookup: links refer to absolute keys even if a scope was given" do
|
39
|
+
I18n.backend.store_translations 'en', {
|
40
|
+
:foo => { :link => :linked, :linked => 'linked in foo' },
|
41
|
+
:linked => 'linked absolutely'
|
42
|
+
}
|
43
|
+
assert_equal 'linked absolutely', I18n.backend.translate('en', :link, :scope => :foo)
|
44
|
+
end
|
27
45
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
:link_to_baz => :'bar.baz'
|
36
|
-
}
|
37
|
-
end
|
46
|
+
define_method "test linked lookup: a link can resolve to a namespace in the middle of a dot-separated key" do
|
47
|
+
I18n.backend.store_translations 'en', {
|
48
|
+
:activemodel => { :errors => { :messages => { :blank => "can't be blank" } } },
|
49
|
+
:activerecord => { :errors => { :messages => :"activemodel.errors.messages" } }
|
50
|
+
}
|
51
|
+
assert_equal "can't be blank", I18n.t(:"activerecord.errors.messages.blank")
|
52
|
+
end
|
38
53
|
end
|
39
54
|
end
|
40
55
|
end
|
data/test/api/lookup.rb
CHANGED
@@ -5,17 +5,21 @@ module Tests
|
|
5
5
|
module Lookup
|
6
6
|
def setup
|
7
7
|
super
|
8
|
-
store_translations(:foo => { :bar => 'bar', :baz => 'baz' })
|
8
|
+
store_translations(:foo => { :bar => 'bar', :baz => 'baz' }, :bla => false)
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
11
|
define_method "test lookup: given a nested key it looks up the nested hash value" do
|
12
12
|
assert_equal 'bar', I18n.t(:'foo.bar')
|
13
13
|
end
|
14
14
|
|
15
|
+
define_method "test make sure we can store a native false value as well" do
|
16
|
+
assert_equal false, I18n.t(:bla)
|
17
|
+
end
|
18
|
+
|
15
19
|
define_method "test lookup: given a missing key, no default and no raise option it returns an error message" do
|
16
20
|
assert_equal "translation missing: en, missing", I18n.t(:missing)
|
17
21
|
end
|
18
|
-
|
22
|
+
|
19
23
|
define_method "test lookup: given a missing key, no default and the raise option it raises MissingTranslationData" do
|
20
24
|
assert_raises(I18n::MissingTranslationData) { I18n.t(:missing, :raise => true) }
|
21
25
|
end
|
@@ -7,8 +7,11 @@ class I18nAllFeaturesApiTest < Test::Unit::TestCase
|
|
7
7
|
include I18n::Backend::Base
|
8
8
|
include I18n::Backend::Cache
|
9
9
|
include I18n::Backend::Metadata
|
10
|
+
include I18n::Backend::Cascade
|
10
11
|
include I18n::Backend::Fallbacks
|
11
12
|
include I18n::Backend::Pluralization
|
13
|
+
include I18n::Backend::Fast
|
14
|
+
include I18n::Backend::InterpolationCompiler
|
12
15
|
end
|
13
16
|
|
14
17
|
def setup
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
4
|
+
|
5
|
+
class I18nCascadeApiTest < Test::Unit::TestCase
|
6
|
+
class Backend
|
7
|
+
include I18n::Backend::Base
|
8
|
+
include I18n::Backend::Cascade
|
9
|
+
end
|
10
|
+
|
11
|
+
def setup
|
12
|
+
I18n.backend = Backend.new
|
13
|
+
super
|
14
|
+
end
|
15
|
+
|
16
|
+
include Tests::Api::Basics
|
17
|
+
include Tests::Api::Defaults
|
18
|
+
include Tests::Api::Interpolation
|
19
|
+
include Tests::Api::Link
|
20
|
+
include Tests::Api::Lookup
|
21
|
+
include Tests::Api::Pluralization
|
22
|
+
include Tests::Api::Procs
|
23
|
+
include Tests::Api::Localization::Date
|
24
|
+
include Tests::Api::Localization::DateTime
|
25
|
+
include Tests::Api::Localization::Time
|
26
|
+
include Tests::Api::Localization::Procs
|
27
|
+
|
28
|
+
define_method "test: make sure we use a backend with Cascade included" do
|
29
|
+
assert_equal Backend, I18n.backend.class
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
4
|
+
|
5
|
+
class I18nFastBackendApiTest < Test::Unit::TestCase
|
6
|
+
include Tests::Api::Basics
|
7
|
+
include Tests::Api::Defaults
|
8
|
+
include Tests::Api::Interpolation
|
9
|
+
include Tests::Api::Link
|
10
|
+
include Tests::Api::Lookup
|
11
|
+
include Tests::Api::Pluralization
|
12
|
+
include Tests::Api::Procs
|
13
|
+
include Tests::Api::Localization::Date
|
14
|
+
include Tests::Api::Localization::DateTime
|
15
|
+
include Tests::Api::Localization::Time
|
16
|
+
include Tests::Api::Localization::Procs
|
17
|
+
|
18
|
+
class FastBackend
|
19
|
+
include I18n::Backend::Base
|
20
|
+
include I18n::Backend::Fast
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup
|
24
|
+
I18n.backend = FastBackend.new
|
25
|
+
super
|
26
|
+
end
|
27
|
+
|
28
|
+
define_method "test: make sure we use the FastBackend backend" do
|
29
|
+
assert_equal FastBackend, I18n.backend.class
|
30
|
+
end
|
31
|
+
end
|
@@ -5,7 +5,7 @@ setup_active_record
|
|
5
5
|
|
6
6
|
class I18nActiveRecordMissingTest < Test::Unit::TestCase
|
7
7
|
def setup
|
8
|
-
store_translations(:en, :i18n => { :
|
8
|
+
store_translations(:en, :i18n => { :plural => { :keys => [:zero, :one, :other] } })
|
9
9
|
|
10
10
|
I18n.backend = I18n::Backend::Chain.new(I18n.backend)
|
11
11
|
I18n.backend.meta_class.send(:include, I18n::Backend::ActiveRecord::Missing)
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
4
|
+
require File.expand_path(File.dirname(__FILE__) + '/simple_test')
|
5
|
+
|
6
|
+
class I18nBackendFastTest < I18nBackendSimpleTest
|
7
|
+
class FastBackend
|
8
|
+
include I18n::Backend::Base
|
9
|
+
include I18n::Backend::Fast
|
10
|
+
end
|
11
|
+
|
12
|
+
def setup
|
13
|
+
super
|
14
|
+
I18n.backend = FastBackend.new
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
class I18nBackendFastSpecificTest < Test::Unit::TestCase
|
19
|
+
class FastBackend
|
20
|
+
include I18n::Backend::Base
|
21
|
+
include I18n::Backend::Fast
|
22
|
+
end
|
23
|
+
|
24
|
+
def setup
|
25
|
+
@backend = FastBackend.new
|
26
|
+
end
|
27
|
+
|
28
|
+
def assert_flattens(expected, nested)
|
29
|
+
assert_equal expected, @backend.send(:flatten_hash, nested)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_hash_flattening_works
|
33
|
+
assert_flattens(
|
34
|
+
{:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}, :"b.f" => {:x=>"x"}, :"b.c"=>"c", :"b.f.x"=>"x", :"b.d"=>"d"},
|
35
|
+
{:a=>'a', :b=>{:c=>'c', :d=>'d', :f=>{:x=>'x'}}}
|
36
|
+
)
|
37
|
+
assert_flattens({:a=>{:b =>['a', 'b']}, :"a.b"=>['a', 'b']}, {:a=>{:b =>['a', 'b']}})
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_pluralization_logic_and_lookup_works
|
41
|
+
counts_hash = {:zero => 'zero', :one => 'one', :other => 'other'}
|
42
|
+
@backend.store_translations :en, {:a => counts_hash}
|
43
|
+
assert_equal 'one', @backend.translate(:en, :a, :count => 1)
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_translation_subtree_retrieval
|
47
|
+
@backend.store_translations :en, :a => {:foo => 'bar'}
|
48
|
+
assert_equal({:foo => 'bar'}, @backend.translate(:en, :a))
|
49
|
+
end
|
50
|
+
end
|
@@ -8,12 +8,12 @@ class I18nBackendHelpersTest < Test::Unit::TestCase
|
|
8
8
|
|
9
9
|
def test_wind_keys
|
10
10
|
hash = { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}
|
11
|
-
expected = { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
|
11
|
+
expected = { :"a.b.c" => "d", :"a.b.e" => "f", :"a.g" => "h", :"i" => "j" }
|
12
12
|
assert_equal expected, @backend.wind_keys(hash)
|
13
13
|
end
|
14
14
|
|
15
15
|
def test_unwind_keys
|
16
|
-
hash = { "a.b.c" => "d", "a.b.e" => "f", "a.g" => "h", "i" => "j" }
|
16
|
+
hash = { "a.b.c" => "d", :"a.b.e" => "f", :"a.g" => "h", "i" => "j" }
|
17
17
|
expected = { "a" => { "b" => { "c" => "d", "e" => "f" }, "g" => "h" }, "i" => "j"}
|
18
18
|
assert_equal expected, @backend.unwind_keys(hash)
|
19
19
|
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require File.expand_path(File.dirname(__FILE__) + '/../../test_helper')
|
4
|
+
|
5
|
+
class InterpolationCompilerTest < Test::Unit::TestCase
|
6
|
+
Compiler = I18n::Backend::InterpolationCompiler::Compiler
|
7
|
+
|
8
|
+
def compile_and_interpolate(str, values = {})
|
9
|
+
Compiler.compile_if_an_interpolation(str).i18n_interpolate(values)
|
10
|
+
end
|
11
|
+
|
12
|
+
def assert_escapes_interpolation_key(expected, malicious_str)
|
13
|
+
assert_equal(expected, Compiler.send(:escape_key_sym, malicious_str))
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_escape_key_properly_escapes
|
17
|
+
assert_escapes_interpolation_key ':"\""', '"'
|
18
|
+
assert_escapes_interpolation_key ':"\\\\"', '\\'
|
19
|
+
assert_escapes_interpolation_key ':"\\\\\""', '\\"'
|
20
|
+
assert_escapes_interpolation_key ':"\#{}"', '#{}'
|
21
|
+
assert_escapes_interpolation_key ':"\\\\\#{}"', '\#{}'
|
22
|
+
end
|
23
|
+
|
24
|
+
def assert_escapes_plain_string(expected, plain_str)
|
25
|
+
assert_equal expected, Compiler.send(:escape_plain_str, plain_str)
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_escape_plain_string_properly_escapes
|
29
|
+
assert_escapes_plain_string '\\"', '"'
|
30
|
+
assert_escapes_plain_string '\'', '\''
|
31
|
+
assert_escapes_plain_string '\\#', '#'
|
32
|
+
assert_escapes_plain_string '\\#{}', '#{}'
|
33
|
+
assert_escapes_plain_string '\\\\\\"','\\"'
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_non_interpolated_strings_or_arrays_dont_get_compiled
|
37
|
+
['abc', '\\{a}}', '{a}}', []].each do |obj|
|
38
|
+
Compiler.compile_if_an_interpolation(obj)
|
39
|
+
assert_equal false, obj.respond_to?(:i18n_interpolate)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_interpolated_string_gets_compiled
|
44
|
+
assert_equal '-A-', compile_and_interpolate('-{{a}}-', :a => 'A')
|
45
|
+
end
|
46
|
+
|
47
|
+
def assert_handles_key(str, key)
|
48
|
+
assert_equal 'A', compile_and_interpolate(str, key => 'A')
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_compiles_fancy_keys
|
52
|
+
assert_handles_key('{{\}}', :'\\' )
|
53
|
+
assert_handles_key('{{#}}', :'#' )
|
54
|
+
assert_handles_key('{{#{}}', :'#{' )
|
55
|
+
assert_handles_key('{{#$SAFE}}', :'#$SAFE')
|
56
|
+
assert_handles_key('{{\000}}', :'\000' )
|
57
|
+
assert_handles_key('{{\'}}', :'\'' )
|
58
|
+
assert_handles_key('{{\'\'}}', :'\'\'' )
|
59
|
+
assert_handles_key('{{a.b}}', :'a.b' )
|
60
|
+
assert_handles_key('{{ }}', :' ' )
|
61
|
+
assert_handles_key('{{:}}', :':' )
|
62
|
+
assert_handles_key("{{:''}}", :":''" )
|
63
|
+
assert_handles_key('{{:"}}', :':"' )
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_str_containing_only_escaped_interpolation_is_handled_correctly
|
67
|
+
assert_equal 'abc {{x}}', compile_and_interpolate('abc \\{{x}}')
|
68
|
+
end
|
69
|
+
|
70
|
+
def test_handles_weired_strings
|
71
|
+
assert_equal '#{} a', compile_and_interpolate('#{} {{a}}', :a => 'a')
|
72
|
+
assert_equal '"#{abc}"', compile_and_interpolate('"#{ab{{a}}c}"', :a => '' )
|
73
|
+
assert_equal 'a}', compile_and_interpolate('{{{a}}}', :'{a' => 'a')
|
74
|
+
assert_equal '"', compile_and_interpolate('"{{a}}', :a => '' )
|
75
|
+
assert_equal 'a{{a}}', compile_and_interpolate('{{a}}\\{{a}}', :a => 'a')
|
76
|
+
assert_equal '\\{{a}}', compile_and_interpolate('\\\\{{a}}')
|
77
|
+
assert_equal '\";eval("a")', compile_and_interpolate('\";eval("{{a}}")', :a => 'a')
|
78
|
+
assert_equal '\";eval("a")', compile_and_interpolate('\";eval("a"){{a}}',:a => '' )
|
79
|
+
assert_equal "\na", compile_and_interpolate("\n{{a}}", :a => 'a')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
class I18nBackendInterpolationCompilerTest < Test::Unit::TestCase
|
84
|
+
class Backend
|
85
|
+
include I18n::Backend::Base
|
86
|
+
include I18n::Backend::InterpolationCompiler
|
87
|
+
end
|
88
|
+
|
89
|
+
include Tests::Api::Interpolation
|
90
|
+
|
91
|
+
def setup
|
92
|
+
I18n.backend = Backend.new
|
93
|
+
super
|
94
|
+
end
|
95
|
+
|
96
|
+
# pre-compile default strings to make sure we are testing I18n::Backend::InterpolationCompiler
|
97
|
+
def interpolate(*args)
|
98
|
+
options = args.last.kind_of?(Hash) ? args.last : {}
|
99
|
+
if default_str = options[:default]
|
100
|
+
I18n::Backend::InterpolationCompiler::Compiler.compile_if_an_interpolation(default_str)
|
101
|
+
end
|
102
|
+
super
|
103
|
+
end
|
104
|
+
|
105
|
+
# I kinda don't think this really is a correct behavior
|
106
|
+
undef :'test interpolation: given no values it does not alter the string'
|
107
|
+
end
|
@@ -39,7 +39,7 @@ class I18nBackendMetadataTest < Test::Unit::TestCase
|
|
39
39
|
end
|
40
40
|
|
41
41
|
define_method "test: translate adds the default to metadata on Strings" do
|
42
|
-
assert_equal 'bar', I18n.t(:foo, :default => 'bar').translation_metadata[:default]
|
42
|
+
assert_equal 'bar', I18n.t(:foo, :default => 'bar', :name => '').translation_metadata[:default]
|
43
43
|
end
|
44
44
|
|
45
45
|
define_method "test: translation adds the interpolation values to metadata on Strings" do
|
data/test/cases/i18n_test.rb
CHANGED
@@ -62,6 +62,11 @@ class I18nTest < Test::Unit::TestCase
|
|
62
62
|
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, [:baz, :buz], [:foo, :bar])
|
63
63
|
end
|
64
64
|
|
65
|
+
def test_normalize_keys_should_not_attempt_to_sym_on_empty_string
|
66
|
+
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, :'baz.buz', :'foo..bar')
|
67
|
+
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, :'baz.buz', :'foo......bar')
|
68
|
+
end
|
69
|
+
|
65
70
|
def test_uses_passed_separator_to_normalize_keys
|
66
71
|
assert_equal [:en, :foo, :bar, :baz, :buz], I18n.send(:normalize_translation_keys, :en, :'baz|buz', :'foo|bar', '|')
|
67
72
|
end
|
data/test/test_helper.rb
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
$:.unshift File.expand_path("../lib", File.dirname(__FILE__))
|
4
|
+
$:.unshift File.expand_path(File.dirname(__FILE__))
|
5
5
|
|
6
|
-
require 'rubygems'
|
7
|
-
require 'test/unit'
|
8
6
|
require 'i18n'
|
9
7
|
require 'i18n/core_ext/object/meta_class'
|
8
|
+
|
9
|
+
require 'rubygems'
|
10
|
+
require 'test/unit'
|
10
11
|
require 'time'
|
11
12
|
require 'yaml'
|
12
13
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: i18n
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sven Fuchs
|
@@ -13,7 +13,7 @@ autorequire:
|
|
13
13
|
bindir: bin
|
14
14
|
cert_chain: []
|
15
15
|
|
16
|
-
date: 2009-12-
|
16
|
+
date: 2009-12-29 00:00:00 +01:00
|
17
17
|
default_executable:
|
18
18
|
dependencies: []
|
19
19
|
|
@@ -30,7 +30,6 @@ files:
|
|
30
30
|
- MIT-LICENSE
|
31
31
|
- README.textile
|
32
32
|
- Rakefile
|
33
|
-
- VERSION
|
34
33
|
- lib/i18n.rb
|
35
34
|
- lib/i18n/backend.rb
|
36
35
|
- lib/i18n/backend/active_record.rb
|
@@ -42,8 +41,10 @@ files:
|
|
42
41
|
- lib/i18n/backend/cascade.rb
|
43
42
|
- lib/i18n/backend/chain.rb
|
44
43
|
- lib/i18n/backend/fallbacks.rb
|
44
|
+
- lib/i18n/backend/fast.rb
|
45
45
|
- lib/i18n/backend/gettext.rb
|
46
46
|
- lib/i18n/backend/helpers.rb
|
47
|
+
- lib/i18n/backend/interpolation_compiler.rb
|
47
48
|
- lib/i18n/backend/metadata.rb
|
48
49
|
- lib/i18n/backend/pluralization.rb
|
49
50
|
- lib/i18n/backend/simple.rb
|
@@ -59,6 +60,7 @@ files:
|
|
59
60
|
- lib/i18n/locale/tag/parents.rb
|
60
61
|
- lib/i18n/locale/tag/rfc4646.rb
|
61
62
|
- lib/i18n/locale/tag/simple.rb
|
63
|
+
- lib/i18n/version.rb
|
62
64
|
- test/all.rb
|
63
65
|
- test/api/basics.rb
|
64
66
|
- test/api/defaults.rb
|
@@ -73,8 +75,10 @@ files:
|
|
73
75
|
- test/api/procs.rb
|
74
76
|
- test/cases/api/active_record_test.rb
|
75
77
|
- test/cases/api/all_features_test.rb
|
78
|
+
- test/cases/api/cascade_test.rb
|
76
79
|
- test/cases/api/chain_test.rb
|
77
80
|
- test/cases/api/fallbacks_test.rb
|
81
|
+
- test/cases/api/fast_test.rb
|
78
82
|
- test/cases/api/pluralization_test.rb
|
79
83
|
- test/cases/api/simple_test.rb
|
80
84
|
- test/cases/backend/active_record/missing_test.rb
|
@@ -83,7 +87,9 @@ files:
|
|
83
87
|
- test/cases/backend/cascade_test.rb
|
84
88
|
- test/cases/backend/chain_test.rb
|
85
89
|
- test/cases/backend/fallbacks_test.rb
|
90
|
+
- test/cases/backend/fast_test.rb
|
86
91
|
- test/cases/backend/helpers_test.rb
|
92
|
+
- test/cases/backend/interpolation_compiler_test.rb
|
87
93
|
- test/cases/backend/metadata_test.rb
|
88
94
|
- test/cases/backend/pluralization_test.rb
|
89
95
|
- test/cases/backend/simple_test.rb
|
@@ -145,8 +151,10 @@ test_files:
|
|
145
151
|
- test/api/procs.rb
|
146
152
|
- test/cases/api/active_record_test.rb
|
147
153
|
- test/cases/api/all_features_test.rb
|
154
|
+
- test/cases/api/cascade_test.rb
|
148
155
|
- test/cases/api/chain_test.rb
|
149
156
|
- test/cases/api/fallbacks_test.rb
|
157
|
+
- test/cases/api/fast_test.rb
|
150
158
|
- test/cases/api/pluralization_test.rb
|
151
159
|
- test/cases/api/simple_test.rb
|
152
160
|
- test/cases/backend/active_record/missing_test.rb
|
@@ -155,7 +163,9 @@ test_files:
|
|
155
163
|
- test/cases/backend/cascade_test.rb
|
156
164
|
- test/cases/backend/chain_test.rb
|
157
165
|
- test/cases/backend/fallbacks_test.rb
|
166
|
+
- test/cases/backend/fast_test.rb
|
158
167
|
- test/cases/backend/helpers_test.rb
|
168
|
+
- test/cases/backend/interpolation_compiler_test.rb
|
159
169
|
- test/cases/backend/metadata_test.rb
|
160
170
|
- test/cases/backend/pluralization_test.rb
|
161
171
|
- test/cases/backend/simple_test.rb
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.3.2
|