summaryrefslogtreecommitdiff
path: root/vendor
diff options
context:
space:
mode:
authorhukl <hukl@eight.local>2009-02-07 15:50:40 +0100
committerhukl <hukl@eight.local>2009-02-07 15:50:40 +0100
commit36a2f1f3c085dd81171cf7d8220770d4ff921ab3 (patch)
tree5ded15331b192bf428af4c94d46d1abb28ef0690 /vendor
parentce9645d0092d42c7bf8781378181ffbd4ff3d088 (diff)
added globalize2 plugin as well as some modifications
which use the new translation facilities. backend mostly.
Diffstat (limited to 'vendor')
-rw-r--r--vendor/plugins/globalize2/.gitignore4
-rw-r--r--vendor/plugins/globalize2/README.textile202
-rw-r--r--vendor/plugins/globalize2/generators/db_backend.rb0
-rw-r--r--vendor/plugins/globalize2/generators/templates/db_backend_migration.rb25
-rw-r--r--vendor/plugins/globalize2/init.rb10
-rw-r--r--vendor/plugins/globalize2/lib/globalize/backend/chain.rb102
-rw-r--r--vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb37
-rw-r--r--vendor/plugins/globalize2/lib/globalize/backend/static.rb59
-rw-r--r--vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb41
-rw-r--r--vendor/plugins/globalize2/lib/globalize/load_path.rb63
-rw-r--r--vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb63
-rw-r--r--vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb81
-rw-r--r--vendor/plugins/globalize2/lib/globalize/model/active_record.rb38
-rw-r--r--vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb77
-rw-r--r--vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb111
-rw-r--r--vendor/plugins/globalize2/lib/globalize/translation.rb32
-rw-r--r--vendor/plugins/globalize2/lib/locale/root.yml3
-rw-r--r--vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb40
-rw-r--r--vendor/plugins/globalize2/notes.textile51
-rw-r--r--vendor/plugins/globalize2/test/backends/chained_test.rb174
-rw-r--r--vendor/plugins/globalize2/test/backends/pluralizing_test.rb63
-rw-r--r--vendor/plugins/globalize2/test/backends/static_test.rb143
-rw-r--r--vendor/plugins/globalize2/test/data/locale/all.yml2
-rw-r--r--vendor/plugins/globalize2/test/data/locale/de-DE.yml2
-rw-r--r--vendor/plugins/globalize2/test/data/locale/en-US.yml2
-rw-r--r--vendor/plugins/globalize2/test/data/locale/en-US/module.yml2
-rw-r--r--vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml2
-rw-r--r--vendor/plugins/globalize2/test/data/locale/root.yml0
-rw-r--r--vendor/plugins/globalize2/test/data/no_globalize_schema.rb11
-rw-r--r--vendor/plugins/globalize2/test/data/post.rb8
-rw-r--r--vendor/plugins/globalize2/test/i18n/missing_translations_test.rb36
-rw-r--r--vendor/plugins/globalize2/test/load_path_test.rb49
-rw-r--r--vendor/plugins/globalize2/test/locale/fallbacks_test.rb154
-rw-r--r--vendor/plugins/globalize2/test/locale/language_tag_test.rb130
-rw-r--r--vendor/plugins/globalize2/test/model/active_record/migration_test.rb73
-rw-r--r--vendor/plugins/globalize2/test/model/active_record/translated_test.rb266
-rw-r--r--vendor/plugins/globalize2/test/test_helper.rb26
-rw-r--r--vendor/plugins/globalize2/test/translation_test.rb54
38 files changed, 2236 insertions, 0 deletions
diff --git a/vendor/plugins/globalize2/.gitignore b/vendor/plugins/globalize2/.gitignore
new file mode 100644
index 0000000..24f36d5
--- /dev/null
+++ b/vendor/plugins/globalize2/.gitignore
@@ -0,0 +1,4 @@
1doc
2spec/spec/db/*
3vendor
4NOTES \ No newline at end of file
diff --git a/vendor/plugins/globalize2/README.textile b/vendor/plugins/globalize2/README.textile
new file mode 100644
index 0000000..dbd7288
--- /dev/null
+++ b/vendor/plugins/globalize2/README.textile
@@ -0,0 +1,202 @@
1h1. Globalize2
2
3Globalize2 is the successor of Globalize for Rails.
4
5It is compatible with and builds on the new "I18n api in Ruby on Rails":http://rails-i18n.org. and adds model translations as well as a bunch of other useful features, such as Locale fallbacks (RFC4647 compliant) and automatic loading of Locale data from defined directory/file locations.
6
7Globalize2 is much more lightweight and modular than its predecessor was. Content translations in Globalize2 use default ActiveRecord features and do not limit any functionality any more.
8
9All features and tools in Globalize2 are implemented in the most unobstrusive and loosely-coupled way possible, so you can pick whatever features or tools you need for your application and combine them with other tools from other libraries or plugins.
10
11h2. Requirements
12
13Rails 2.2 (currently Rails edge)
14
15h2. Installation
16
17To install Globalize2 with its default setup just use:
18
19<pre><code>
20script/plugin install git://github.com/joshmh/globalize2.git
21</code></pre>
22
23This will:
24
25* activate model translations
26* set I18n.load_path to an instance of Globalize::LoadPath
27* set I18n.backend to an instance of Globalize::Backend::Static
28
29h2. Configuration
30
31You might want to add additional configuration to an initializer, e.g. config/initializers/globalize.rb
32
33h2. Model translations
34
35Model translations (or content translations) allow you to translate your models' attribute values. E.g.
36
37<pre><code>
38class Post < ActiveRecord::Base
39 translates :title, :text
40end
41</code></pre>
42
43Allows you to values for the attributes :title and :text per locale:
44
45<pre><code>
46I18n.locale = :en
47post.title # Globalize2 rocks!
48
49I18n.locale = :he
50post.title # גלובאלייז2 שולט!
51</code></pre>
52
53In order to make this work, you'll need to add the appropriate translation tables. Globalize2 comes with a handy helper method to help you do this. It's called @create_translation_table!@. Here's an example:
54
55<pre><code>
56class CreatePosts < ActiveRecord::Migration
57 def self.up
58 create_table :posts do |t|
59 t.timestamps
60 end
61 Post.create_translation_table! :title => :string, :text => :text
62 end
63 def self.down
64 drop_table :posts
65 Post.drop_translation_table!
66 end
67end
68</code></pre>
69
70Note that the ActiveRecord model @Post@ must already exist and have a @translates@ directive listing the translated fields.
71
72h2. Globalize::Backend::Static
73
74Globalize2 ships with a Static backend that builds on the Simple backend from the I18n library (which is shipped with Rails) and adds the following features:
75
76* It uses locale fallbacks when looking up translation data.
77* It returns an instance of Globalize::Translation::Static instead of a plain Ruby String as a translation.
78* It allows to hook in custom pluralization logic as lambdas.
79
80h2. Custom pluralization logic
81
82The Simple backend has its pluralization algorithm baked in hardcoded. This algorithm is only suitable for English and other languages that have the same pluralization rules. It is not suitable for, e.g., Czech though.
83
84To add custom pluralization logic to Globalize' Static backend you can do something like this:
85
86<pre><code>
87@backend.add_pluralizer :cz, lambda{|c|
88 c == 1 ? :one : (2..4).include?(c) ? :few : :other
89}
90</code></pre>
91
92h2. Locale Fallbacks
93
94Globalize2 ships with a Locale fallback tool which extends the I18n module to hold a fallbacks instance which is set to an instance of Globalize::Locale::Fallbacks by default but can be swapped with a different implementation.
95
96Globalize2 fallbacks will compute a number of other locales for a given locale. For example:
97
98<pre><code>
99I18n.fallbacks[:"es-MX"] # => [:"es-MX", :es, :"en-US", :en]
100</code></pre>
101
102Globalize2 fallbacks always fall back to
103
104* all parents of a given locale (e.g. :es for :"es-MX"),
105* then to the fallbacks' default locales and all of their parents and
106* finally to the :root locale.
107
108The default locales are set to [:"en-US"] by default but can be set to something else. The root locale is a concept borrowed from "CLDR":http://unicode.org and makes sense for storing common locale data which works as a last default fallback (e.g. "ltr" for bidi directions).
109
110One can additionally add any number of additional fallback locales manually. These will be added before the default locales to the fallback chain. For example:
111
112<pre><code>
113fb = I18n.fallbacks
114
115fb.map :ca => :"es-ES"
116fb[:ca] # => [:ca, :"es-ES", :es, :"en-US", :en]
117
118fb.map :"ar-PS" => :"he-IL"
119fb[:"ar-PS"] # => [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en]
120fb[:"ar-EG"] # => [:"ar-EG", :ar, :"en-US", :en]
121
122fb.map :sms => [:"se-FI", :"fi-FI"]
123fb[:sms] # => [:sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en]
124</code></pre>
125
126h2. Globalize::LoadPath
127
128Globalize2 replaces the plain Ruby array that is set to I18n.load_path by default through an instance of Globalize::LoadPath.
129
130This object can be populated with both paths to files and directories. If a path to a directory is added to it it will look up all locale data files present in that directory enforcing the following convention:
131
132<pre><code>
133I18n.load_path << "#{RAILS_ROOT}/lib/locales"
134
135# will load all the following files if present:
136lib/locales/all.yml
137lib/locales/fr.yml
138lib/locales/fr/*.yaml
139lib/locales/ru.yml
140lib/locales/ru/*.yaml
141...
142</code></pre>
143
144One can also specify which locales are used. By default this is set to "*" meaning that files for all locales are added. To define that only files for the locale :es are added one can specify:
145
146<pre><code>
147I18n.load_path.locales = [:es]
148</code></pre>
149
150One can also specify which file extensions are used. By default this is set to ['rb', 'yml'] so plain Ruby and YAML files are added if found. To define that only *.sql files are added one can specify:
151
152<pre><code>
153I18n.load_path.extensions = ['sql']
154</code></pre>
155
156Note that Globalize::LoadPath "expands" a directory to its contained file paths immediately when you add it to the load_path. Thus, if you change the locales or extensions settings in the middle of your application the change won't be applied to already added file paths.
157
158
159h2. Globalize::Translation classes
160
161Globalize2's Static backend as well as Globalize2 model translations return instances of Globalize::Translation classes (instead of plain Ruby Strings). These are simple and lightweight value objects that carry some additional meta data about the translation and how it was looked up.
162
163Model translations return instances of Globalize::Translation::Attribute, the Static backend returns instances of Globalize::Translation::Static.
164
165For example:
166
167<pre><code>
168I18n.locale = :de
169
170# Translation::Attribute
171title = Post.first.title # assuming that no translation can be found:
172title.locale # => :en
173title.requested_locale # => :de
174title.fallback? # => true
175
176# Translation::Static
177rails = I18n.t :rails # assuming that no translation can be found:
178rails.locale # => :en
179rails.requested_locale # => :de
180rails.fallback? # => true
181rails.options # returns the options passed to #t
182rails.plural_key # returns the plural_key (e.g. :one, :other)
183rails.original # returns the original translation with no values
184 # interpolated to it (e.g. "Hi {{name}}!")
185</code></pre>
186
187h2. Missing Translations Log Handler
188
189A simple exception handler that behaves like the default exception handler but additionally logs missing translations to a given log.
190
191Useful for identifying missing translations during testing.
192
193E.g.
194
195 require 'globalize/i18n/missing_translations_log_handler
196 I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
197 I18n.exception_handler = :missing_translations_log_handler
198
199To set up a different log file:
200
201 logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
202 I18n.missing_translations_logger = logger
diff --git a/vendor/plugins/globalize2/generators/db_backend.rb b/vendor/plugins/globalize2/generators/db_backend.rb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/plugins/globalize2/generators/db_backend.rb
diff --git a/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb b/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
new file mode 100644
index 0000000..d4513a5
--- /dev/null
+++ b/vendor/plugins/globalize2/generators/templates/db_backend_migration.rb
@@ -0,0 +1,25 @@
1class ActsAsTaggableMigration < ActiveRecord::Migration
2 def self.up
3 create_table :globalize_translations do |t|
4 t.string :locale, :null => false
5 t.string :key, :null => false
6 t.string :translation
7 t.timestamps
8 end
9
10# TODO: FINISH DOING MIGRATION -- stopped in the middle
11
12 create_table :globalize_translations_map do |t|
13 t.string :key, :null => false
14 t.integer :translation_id, :null => false
15 end
16
17 add_index :taggings, :tag_id
18 add_index :taggings, [:taggable_id, :taggable_type]
19 end
20
21 def self.down
22 drop_table :globalize_translations
23 drop_table :tags
24 end
25end
diff --git a/vendor/plugins/globalize2/init.rb b/vendor/plugins/globalize2/init.rb
new file mode 100644
index 0000000..7b5428e
--- /dev/null
+++ b/vendor/plugins/globalize2/init.rb
@@ -0,0 +1,10 @@
1require 'rails_edge_load_path_patch.rb' unless I18n.respond_to?(:load_path)
2
3ActiveRecord::Base.send :include, Globalize::Model::ActiveRecord::Translated
4
5I18n.backend = Globalize::Backend::Static.new
6
7I18n.load_path = Globalize::LoadPath.new I18n.load_path
8I18n.load_path << "#{File.dirname(__FILE__)}/lib/locale"
9I18n.load_path << "#{RAILS_ROOT}/lib/locale"
10
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/chain.rb b/vendor/plugins/globalize2/lib/globalize/backend/chain.rb
new file mode 100644
index 0000000..bb8679e
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/backend/chain.rb
@@ -0,0 +1,102 @@
1module I18n
2 class << self
3 def chain_backends(*args)
4 self.backend = Globalize::Backend::Chain.new(*args)
5 end
6 end
7end
8
9module Globalize
10 module Backend
11 class Chain
12 def initialize(*args)
13 add(*args) unless args.empty?
14 end
15
16 # Change this to a) accept any number of backends and b) accept classes.
17 # When classes are passed instantiate them and add the instances as backends.
18 # Return the added backends from #add.
19 #
20 # Add an initialize method that accepts the same arguments and passes them
21 # to #add, so we could:
22 # I18n.backend = Globalize::Backend::Chain.new(Globalize::Backend::Foo, Globalize::Backend::Bar)
23 # Globalize::Backend::Chain.new(:foo, :bar)
24 # Globalize.chain_backends :foo, :bar
25 def add(*backends)
26 backends.each do |backend|
27 backend = Globalize::Backend.const_get(backend.to_s.capitalize) if backend.is_a? Symbol
28 backend = backend.new if backend.is_a? Class
29 self.backends << backend
30 end
31 end
32
33 def load_translations(*args)
34 backends.each{|backend| backend.load_translations(*args) }
35 end
36
37 # For defaults:
38 # Never pass any default option to the backends but instead implement our own default
39 # mechanism (e.g. symbols as defaults would need to be passed to the whole chain to
40 # be translated).
41 #
42 # For namespace lookup:
43 # Only return if the result is not a hash OR count is not present, otherwise merge them.
44 # So in effect the count variable would control whether we have a namespace lookup or a
45 # pluralization going on.
46 #
47 # Exceptions:
48 # Make sure that we catch MissingTranslationData exceptions and raise
49 # one in the end when no translation was found at all.
50 #
51 # For bulk translation:
52 # If the key is an array we need to call #translate for each of the
53 # keys and collect the results.
54
55 def translate(locale, key, options = {})
56 raise I18n::InvalidLocale.new(locale) if locale.nil?
57 return key.map{|k| translate locale, k, options } if key.is_a? Array
58
59 default = options.delete(:default)
60 result = backends.inject({}) do |namespace, backend|
61 begin
62 translation = backend.translate(locale.to_sym, key, options)
63 if namespace_lookup?(translation, options)
64 namespace.merge! translation
65 elsif translation
66 return translation
67 end
68 rescue I18n::MissingTranslationData
69 end
70 end
71 result || default(locale, default, options) || raise(I18n::MissingTranslationData.new(locale, key, options))
72 end
73
74 def localize(locale, object, format = :default)
75 backends.each do |backend|
76 result = backend.localize(locale, object, format) and return result
77 end
78 end
79
80 protected
81 def backends
82 @backends ||= []
83 end
84
85 def default(locale, default, options = {})
86 case default
87 when String then default
88 when Symbol then translate locale, default, options
89 when Array then default.each do |obj|
90 result = default(locale, obj, options.dup) and return result
91 end and nil
92 end
93 rescue I18n::MissingTranslationData
94 nil
95 end
96
97 def namespace_lookup?(result, options)
98 result.is_a?(Hash) and not options.has_key?(:count)
99 end
100 end
101 end
102end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb b/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb
new file mode 100644
index 0000000..80016f2
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/backend/pluralizing.rb
@@ -0,0 +1,37 @@
1require 'i18n/backend/simple'
2
3module Globalize
4 module Backend
5 class Pluralizing < I18n::Backend::Simple
6 def pluralize(locale, entry, count)
7 return entry unless entry.is_a?(Hash) and count
8 key = :zero if count == 0 && entry.has_key?(:zero)
9 key ||= pluralizer(locale).call(count)
10 raise InvalidPluralizationData.new(entry, count) unless entry.has_key?(key)
11 translation entry[key], :plural_key => key
12 end
13
14 def add_pluralizer(locale, pluralizer)
15 pluralizers[locale.to_sym] = pluralizer
16 end
17
18 def pluralizer(locale)
19 pluralizers[locale.to_sym] || default_pluralizer
20 end
21
22 protected
23 def default_pluralizer
24 pluralizers[:en]
25 end
26
27 def pluralizers
28 @pluralizers ||= { :en => lambda{|n| n == 1 ? :one : :other } }
29 end
30
31 # Overwrite this method to return something other than a String
32 def translation(string, attributes)
33 string
34 end
35 end
36 end
37end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/backend/static.rb b/vendor/plugins/globalize2/lib/globalize/backend/static.rb
new file mode 100644
index 0000000..3903517
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/backend/static.rb
@@ -0,0 +1,59 @@
1require 'globalize/backend/pluralizing'
2require 'globalize/locale/fallbacks'
3require 'globalize/translation'
4
5module Globalize
6 module Backend
7 class Static < Pluralizing
8 def initialize(*args)
9 add(*args) unless args.empty?
10 end
11
12 def translate(locale, key, options = {})
13 result, default, fallback = nil, options.delete(:default), nil
14 I18n.fallbacks[locale].each do |fallback|
15 begin
16 result = super(fallback, key, options) and break
17 rescue I18n::MissingTranslationData
18 end
19 end
20 result ||= default locale, default, options
21
22 attrs = {:requested_locale => locale, :locale => fallback, :key => key, :options => options}
23 translation(result, attrs) || raise(I18n::MissingTranslationData.new(locale, key, options))
24 end
25
26 protected
27
28 alias :orig_interpolate :interpolate unless method_defined? :orig_interpolate
29 def interpolate(locale, string, values = {})
30 result = orig_interpolate(locale, string, values)
31 translation = translation(string)
32 translation.nil? ? result : translation.replace(result)
33 end
34
35 def translation(result, meta = nil)
36 return unless result
37
38 case result
39 when Numeric
40 result
41 when String
42 result = Translation::Static.new(result) unless result.is_a? Translation::Static
43 result.set_meta meta
44 result
45 when Hash
46 Hash[*result.map do |key, value|
47 [key, translation(value, meta)]
48 end.flatten]
49 when Array
50 result.map do |value|
51 translation(value, meta)
52 end
53 else
54 raise "unexpected translation type: #{result.inspect}"
55 end
56 end
57 end
58 end
59end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb b/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb
new file mode 100644
index 0000000..3f06ac2
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/i18n/missing_translations_log_handler.rb
@@ -0,0 +1,41 @@
1# A simple exception handler that behaves like the default exception handler
2# but additionally logs missing translations to a given log.
3#
4# Useful for identifying missing translations during testing.
5#
6# E.g.
7#
8# require 'globalize/i18n/missing_translations_log_handler
9# I18n.missing_translations_logger = RAILS_DEFAULT_LOGGER
10# I18n.exception_handler = :missing_translations_log_handler
11#
12# To set up a different log file:
13#
14# logger = Logger.new("#{RAILS_ROOT}/log/missing_translations.log")
15# I18n.missing_translations_logger = logger
16
17module I18n
18 @@missing_translations_logger = nil
19
20 class << self
21 def missing_translations_logger
22 @@missing_translations_logger ||= begin
23 require 'logger' unless defined?(Logger)
24 Logger.new(STDOUT)
25 end
26 end
27
28 def missing_translations_logger=(logger)
29 @@missing_translations_logger = logger
30 end
31
32 def missing_translations_log_handler(exception, locale, key, options)
33 if MissingTranslationData === exception
34 missing_translations_logger.warn(exception.message)
35 return exception.message
36 else
37 raise exception
38 end
39 end
40 end
41end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/load_path.rb b/vendor/plugins/globalize2/lib/globalize/load_path.rb
new file mode 100644
index 0000000..a49825b
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/load_path.rb
@@ -0,0 +1,63 @@
1# Locale load_path and Locale loading support.
2#
3# To use this include the Globalize::LoadPath::I18n module to I18n like this:
4#
5# I18n.send :include, Globalize::LoadPath::I18n
6#
7# Clients can add load_paths using:
8#
9# I18n.load_path.add load_path, 'rb', 'yml' # pass any number of extensions like this
10# I18n.load_path << 'path/to/dir' # usage without an extension, defaults to 'yml'
11#
12# And load locale data using either of:
13#
14# I18n.load_locales 'en-US', 'de-DE'
15# I18n.load_locale 'en-US'
16#
17# This will lookup all files named like:
18#
19# 'path/to/dir/all.yml'
20# 'path/to/dir/en-US.yml'
21# 'path/to/dir/en-US/*.yml'
22#
23# The filenames will be passed to I18n.load_translations which delegates to
24# the backend. So the actual behaviour depends on the implementation of the
25# backend. I18n::Backend::Simple will be able to read YAML and plain Ruby
26# files. See the documentation for I18n.load_translations for details.
27
28module Globalize
29 class LoadPath < Array
30 def extensions
31 @extensions ||= ['rb', 'yml']
32 end
33 attr_writer :extensions
34
35 def locales
36 @locales ||= ['*']
37 end
38 attr_writer :locales
39
40 def <<(path)
41 push path
42 end
43
44 def push(*paths)
45 super(*paths.map{|path| filenames(path) }.flatten.uniq.sort)
46 end
47
48 protected
49
50 def filenames(path)
51 return [path] if File.file? path
52 patterns(path).map{|pattern| Dir[pattern] }
53 end
54
55 def patterns(path)
56 locales.map do |locale|
57 extensions.map do |extension|
58 %W(#{path}/all.#{extension} #{path}/#{locale}.#{extension} #{path}/#{locale}/**/*.#{extension})
59 end
60 end.flatten.uniq
61 end
62 end
63end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb b/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb
new file mode 100644
index 0000000..c4acd57
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/locale/fallbacks.rb
@@ -0,0 +1,63 @@
1require 'globalize/locale/language_tag'
2
3module I18n
4 @@fallbacks = nil
5
6 class << self
7 # Returns the current fallbacks. Defaults to +Globalize::Locale::Fallbacks+.
8 def fallbacks
9 @@fallbacks ||= Globalize::Locale::Fallbacks.new
10 end
11
12 # Sets the current fallbacks. Used to set a custom fallbacks instance.
13 def fallbacks=(fallbacks)
14 @@fallbacks = fallbacks
15 end
16 end
17end
18
19module Globalize
20 module Locale
21 class Fallbacks < Hash
22 def initialize(*defaults)
23 @map = {}
24 map defaults.pop if defaults.last.is_a?(Hash)
25
26 defaults = [I18n.default_locale.to_sym] if defaults.empty?
27 self.defaults = defaults
28 end
29
30 def defaults=(defaults)
31 @defaults = defaults.map{|default| compute(default, false) }.flatten << :root
32 end
33 attr_reader :defaults
34
35 def [](tag)
36 tag = tag.to_sym
37 has_key?(tag) ? fetch(tag) : store(tag, compute(tag))
38 end
39
40 def map(mappings)
41 mappings.each do |from, to|
42 from, to = from.to_sym, Array(to)
43 to.each do |to|
44 @map[from] ||= []
45 @map[from] << to.to_sym
46 end
47 end
48 end
49
50 protected
51
52 def compute(tags, include_defaults = true)
53 result = Array(tags).collect do |tag|
54 tags = LanguageTag::tag(tag.to_sym).parents(true).map! {|t| t.to_sym }
55 tags.each{|tag| tags += compute(@map[tag]) if @map[tag] }
56 tags
57 end.flatten
58 result.push *defaults if include_defaults
59 result.uniq
60 end
61 end
62 end
63end
diff --git a/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb b/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb
new file mode 100644
index 0000000..d9aae54
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/locale/language_tag.rb
@@ -0,0 +1,81 @@
1# for specifications see http://en.wikipedia.org/wiki/IETF_language_tag
2#
3# SimpleParser does not implement advanced usages such as grandfathered tags
4
5module Globalize
6 module Locale
7 module Rfc4646
8 SUBTAGS = [:language, :script, :region, :variant, :extension, :privateuse, :grandfathered]
9 FORMATS = {:language => :downcase, :script => :capitalize, :region => :upcase, :variant => :downcase}
10 end
11
12 class LanguageTag < Struct.new(*Rfc4646::SUBTAGS)
13 class << self
14 def parser
15 @@parser ||= SimpleParser
16 end
17
18 def parser=(parser)
19 @@parser = parser
20 end
21
22 def tag(tag)
23 matches = parser.match(tag)
24 new *matches if matches
25 end
26 end
27
28 Rfc4646::FORMATS.each do |name, format|
29 define_method(name) { self[name].send(format) unless self[name].nil? }
30 end
31
32 def to_sym
33 to_s.to_sym
34 end
35
36 def to_s
37 @tag ||= to_a.compact.join("-")
38 end
39
40 def to_a
41 members.collect {|attr| self.send(attr) }
42 end
43
44 def parent
45 segs = to_a.compact
46 segs.length < 2 ? nil : LanguageTag.tag(segs[0..(segs.length-2)].join('-'))
47 end
48
49 def parents(include_self = true)
50 result, parent = [], self.dup
51 result << parent if include_self
52 while parent = parent.parent
53 result << parent
54 end
55 result
56 end
57
58 module SimpleParser
59 PATTERN = %r{\A(?:
60 ([a-z]{2,3}(?:(?:-[a-z]{3}){0,3})?|[a-z]{4}|[a-z]{5,8}) # language
61 (?:-([a-z]{4}))? # script
62 (?:-([a-z]{2}|\d{3}))? # region
63 (?:-([0-9a-z]{5,8}|\d[0-9a-z]{3}))* # variant
64 (?:-([0-9a-wyz](?:-[0-9a-z]{2,8})+))* # extension
65 (?:-(x(?:-[0-9a-z]{1,8})+))?| # privateuse subtag
66 (x(?:-[0-9a-z]{1,8})+)| # privateuse tag
67 /* ([a-z]{1,3}(?:-[0-9a-z]{2,8}){1,2}) */ # grandfathered
68 )\z}xi
69
70 class << self
71 def match(tag)
72 c = PATTERN.match(tag.to_s).captures
73 c[0..4] << (c[5].nil? ? c[6] : c[5]) << c[7] # TODO c[7] is grandfathered, throw a NotImplemented exception here?
74 rescue
75 false
76 end
77 end
78 end
79 end
80 end
81end
diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb
new file mode 100644
index 0000000..450729c
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/model/active_record.rb
@@ -0,0 +1,38 @@
1require 'globalize/translation'
2require 'globalize/locale/fallbacks'
3require 'globalize/model/active_record/adapter'
4require 'globalize/model/active_record/translated'
5
6module Globalize
7 module Model
8 module ActiveRecord
9 class << self
10 def create_proxy_class(klass)
11 Object.const_set "#{klass.name}Translation", Class.new(::ActiveRecord::Base){
12 belongs_to "#{klass.name.underscore}".intern
13
14 def locale
15 read_attribute(:locale).to_sym
16 end
17
18 def locale=(locale)
19 write_attribute(:locale, locale.to_s)
20 end
21 }
22 end
23
24 def define_accessors(klass, attr_names)
25 attr_names.each do |attr_name|
26 klass.send :define_method, attr_name, lambda {
27 globalize.fetch I18n.locale, attr_name
28 }
29 klass.send :define_method, "#{attr_name}=", lambda {|val|
30 globalize.stash I18n.locale, attr_name, val
31 self[attr_name] = val
32 }
33 end
34 end
35 end
36 end
37 end
38end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb
new file mode 100644
index 0000000..12d7564
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/model/active_record/adapter.rb
@@ -0,0 +1,77 @@
1module Globalize
2 module Model
3 class AttributeStash < Hash
4 def read(locale, attr_name)
5 locale = locale.to_sym
6 self[locale] ||= {}
7 self[locale][attr_name]
8 end
9
10 def write(locale, attr_name, value)
11 locale = locale.to_sym
12 self[locale] ||= {}
13 self[locale][attr_name] = value
14 end
15 end
16
17 class Adapter
18 def initialize(record)
19 @record = record
20 @cache = AttributeStash.new
21 @stash = AttributeStash.new
22 end
23
24 def fetch(locale, attr_name)
25 # locale = I18n.locale
26 @cache.read(locale, attr_name) || begin
27 value = fetch_attribute locale, attr_name
28 @cache.write locale, attr_name, value if value && value.locale == locale
29 value
30 end
31 end
32
33 def stash(locale, attr_name, value)
34 @stash.write locale, attr_name, value
35 @cache.write locale, attr_name, value
36 end
37
38 def update_translations!
39 @stash.each do |locale, attrs|
40 translation = @record.globalize_translations.find_or_initialize_by_locale(locale.to_s)
41 attrs.each{|attr_name, value| translation[attr_name] = value }
42 translation.save!
43 end
44 @stash.clear
45 end
46
47 # Clears the cache
48 def clear
49 @cache.clear
50 end
51
52 private
53
54 def fetch_attribute(locale, attr_name)
55 fallbacks = I18n.fallbacks[locale].map{|tag| tag.to_s}.map(&:to_sym)
56 translations = @record.globalize_translations.by_locales(fallbacks)
57 result, requested_locale = nil, locale
58
59 # Walk through the fallbacks, starting with the current locale itself, and moving
60 # to the next best choice, until we find a match.
61 # Check the @globalize_set_translations cache first to see if we've just changed the
62 # attribute and not saved yet.
63 fallbacks.each do |fallback|
64 result = @stash.read(fallback, attr_name) || begin
65 translation = translations.detect {|tr| tr.locale == fallback }
66 translation && translation.send(attr_name)
67 end
68 if result
69 locale = fallback
70 break
71 end
72 end
73 result && Translation::Attribute.new(result, :locale => locale, :requested_locale => requested_locale)
74 end
75 end
76 end
77end
diff --git a/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb
new file mode 100644
index 0000000..710cde5
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/model/active_record/translated.rb
@@ -0,0 +1,111 @@
1module Globalize
2 module Model
3
4 class MigrationError < StandardError; end
5 class UntranslatedMigrationField < MigrationError; end
6 class MigrationMissingTranslatedField < MigrationError; end
7 class BadMigrationFieldType < MigrationError; end
8
9 module ActiveRecord
10 module Translated
11 def self.included(base)
12 base.extend ActMethods
13 end
14
15 module ActMethods
16 def translates(*attr_names)
17 options = attr_names.extract_options!
18 options[:translated_attributes] = attr_names
19
20 # Only set up once per class
21 unless included_modules.include? InstanceMethods
22 class_inheritable_accessor :globalize_options
23 include InstanceMethods
24 extend ClassMethods
25
26 proxy_class = Globalize::Model::ActiveRecord.create_proxy_class(self)
27 has_many :globalize_translations, :class_name => proxy_class.name, :extend => Extensions
28
29 after_save :update_globalize_record
30
31 def i18n_attr(attribute_name)
32 self.name.underscore + "_translations.#{attribute_name}"
33 end
34 end
35
36 self.globalize_options = options
37 Globalize::Model::ActiveRecord.define_accessors(self, attr_names)
38
39 # Import any callbacks that have been defined by extensions to Globalize2
40 # and run them.
41 extend Callbacks
42 Callbacks.instance_methods.each {|cb| send cb }
43 end
44 end
45
46 # Dummy Callbacks module. Extensions to Globalize2 can insert methods into here
47 # and they'll be called at the end of the translates class method.
48 module Callbacks
49 end
50
51 # Extension to the has_many :globalize_translations association
52 module Extensions
53 def by_locales(locales)
54 find :all, :conditions => { :locale => locales.map(&:to_s) }
55 end
56 end
57
58 module ClassMethods
59 def method_missing(method, *args)
60 if method.to_s =~ /^find_by_(\w+)$/ && globalize_options[:translated_attributes].include?($1.to_sym)
61 find(:first, :joins => :globalize_translations,
62 :conditions => [i18n_attr($1)+" = ? AND "+i18n_attr('locale')+" IN (?)",
63 args.first,I18n.fallbacks[I18n.locale].map{|tag| tag.to_s}])
64 else
65 super
66 end
67 end
68
69 def create_translation_table!(fields)
70 translated_fields = self.globalize_options[:translated_attributes]
71 translated_fields.each do |f|
72 raise MigrationMissingTranslatedField, "Missing translated field #{f}" unless fields[f]
73 end
74 fields.each do |name, type|
75 unless translated_fields.member? name
76 raise UntranslatedMigrationField, "Can't migrate untranslated field: #{name}"
77 end
78 unless [ :string, :text ].member? type
79 raise BadMigrationFieldType, "Bad field type for #{name}, should be :string or :text"
80 end
81 end
82 translation_table_name = self.name.underscore + '_translations'
83 self.connection.create_table(translation_table_name) do |t|
84 t.references self.table_name.singularize
85 t.string :locale
86 fields.each do |name, type|
87 t.column name, type
88 end
89 t.timestamps
90 end
91 end
92
93 def drop_translation_table!
94 translation_table_name = self.name.underscore + '_translations'
95 self.connection.drop_table translation_table_name
96 end
97 end
98
99 module InstanceMethods
100 def globalize
101 @globalize ||= Adapter.new self
102 end
103
104 def update_globalize_record
105 globalize.update_translations!
106 end
107 end
108 end
109 end
110 end
111end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/globalize/translation.rb b/vendor/plugins/globalize2/lib/globalize/translation.rb
new file mode 100644
index 0000000..a80afcd
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/globalize/translation.rb
@@ -0,0 +1,32 @@
1module Globalize
2 # Translations are simple value objects that carry some context information
3 # alongside the actual translation string.
4
5 class Translation < String
6 class Attribute < Translation
7 attr_accessor :requested_locale, :locale, :key
8 end
9
10 class Static < Translation
11 attr_accessor :requested_locale, :locale, :key, :options, :plural_key, :original
12
13 def initialize(string, meta = nil)
14 self.original = string
15 super
16 end
17 end
18
19 def initialize(string, meta = nil)
20 set_meta meta
21 super string
22 end
23
24 def fallback?
25 locale.to_sym != requested_locale.to_sym
26 end
27
28 def set_meta(meta)
29 meta.each {|name, value| send :"#{name}=", value } if meta
30 end
31 end
32end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/locale/root.yml b/vendor/plugins/globalize2/lib/locale/root.yml
new file mode 100644
index 0000000..2ec2b3b
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/locale/root.yml
@@ -0,0 +1,3 @@
1root:
2 bidi:
3 direction: left-to-right \ No newline at end of file
diff --git a/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb b/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb
new file mode 100644
index 0000000..e6f90d8
--- /dev/null
+++ b/vendor/plugins/globalize2/lib/rails_edge_load_path_patch.rb
@@ -0,0 +1,40 @@
1module I18n
2 @@load_path = nil
3 @@default_locale = :'en-US'
4
5 class << self
6 def load_path
7 @@load_path ||= []
8 end
9
10 def load_path=(load_path)
11 @@load_path = load_path
12 end
13 end
14end
15
16I18n::Backend::Simple.module_eval do
17 def initialized?
18 @initialized ||= false
19 end
20
21 protected
22
23 def init_translations
24 load_translations(*I18n.load_path)
25 @initialized = true
26 end
27
28 def lookup(locale, key, scope = [])
29 return unless key
30 init_translations unless initialized?
31 keys = I18n.send :normalize_translation_keys, locale, key, scope
32 keys.inject(translations){|result, k| result[k.to_sym] or return nil }
33 end
34end
35
36rails_dir = File.expand_path "#{File.dirname(__FILE__)}/../../../rails/"
37paths = %w(actionpack/lib/action_view/locale/en-US.yml
38 activerecord/lib/active_record/locale/en-US.yml
39 activesupport/lib/active_support/locale/en-US.yml)
40paths.each{|path| I18n.load_path << "#{rails_dir}/#{path}" }
diff --git a/vendor/plugins/globalize2/notes.textile b/vendor/plugins/globalize2/notes.textile
new file mode 100644
index 0000000..b686f41
--- /dev/null
+++ b/vendor/plugins/globalize2/notes.textile
@@ -0,0 +1,51 @@
1Stopped DB Backend in the middle, here's where we left off:
2
3h1. Some Notes
4
5* Started doing the migration generator in generators/db_backend.rb
6* Translation keys will be in dotted string format
7* Question: Do we need a plural_key column, or can we build it in to the dotted key?
8* We will probably have to code the following methods from scratch, to optimize db calls:
9** translate
10** localize
11** pluralize
12* We should refactor @interpolation@ code so that it can be included into backend code without inheriting SimpleBackend
13** Rationale: interpolation is something done entirely after a string is fetched from the data store
14** Alternately, it could be done from within the I18n module
15
16h1. Schema
17
18There will be two db tables.
19
20# globalize_translations will have: locale, key, translation, created_at, updated_at.
21# globalize_translations_map will have: key, translation_id.
22
23globalize_translations_map will let us easily fetch entire sub-trees of namespaces.
24However, this table may not be necessary, as it may be feasible to just use key LIKE "some.namespace.%".
25
26h1. Caching
27
28We'll almost certainly want to implement caching in the backend. Should probably be a customized
29implementation based on the Rails caching mechanism, to support memcached, etc.
30
31h1. Queries
32
33We'll want to pull in lots of stuff at once and return a single translation based on some
34quick Ruby selection. The query will look something like this:
35
36<pre>
37<code>
38SELECT * FROM globalize_translations
39WHERE locale in (<fallbacks>) AND
40key IN (key, default_key)
41</code>
42</pre>
43
44The Ruby code would then pick the first translation that satisfies a fallback, in fallback order.
45Of course, the records with the supplied key would take precedence of those with the default key.
46
47h1. Misc
48
49We should revisit the :zero plural code. On the one hand it's certainly useful for
50many apps in many languages. On the other hand it's not mentioned in CLDR, and not a real
51concept in language pluralization. Right now, I'm feeling it's still a good idea to keep it in.
diff --git a/vendor/plugins/globalize2/test/backends/chained_test.rb b/vendor/plugins/globalize2/test/backends/chained_test.rb
new file mode 100644
index 0000000..bc45179
--- /dev/null
+++ b/vendor/plugins/globalize2/test/backends/chained_test.rb
@@ -0,0 +1,174 @@
1require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2require 'globalize/backend/chain'
3
4module Globalize
5 module Backend
6 class Dummy
7 def translate(locale, key, options = {})
8 end
9 end
10 end
11end
12
13class ChainedTest < ActiveSupport::TestCase
14
15 test "instantiates a chained backend and sets test as backend" do
16 assert_nothing_raised { I18n.chain_backends }
17 assert_instance_of Globalize::Backend::Chain, I18n.backend
18 end
19
20 test "passes all given arguments to the chained backends #initialize method" do
21 Globalize::Backend::Chain.expects(:new).with(:spec, :simple)
22 I18n.chain_backends :spec, :simple
23 end
24
25 test "passes all given arguments to #add assuming that they are backends" do
26 # no idea how to spec that
27 end
28end
29
30class AddChainedTest < ActiveSupport::TestCase
31 def setup
32 I18n.backend = Globalize::Backend::Chain.new
33 end
34
35 test "accepts an instance of a backend" do
36 assert_nothing_raised { I18n.backend.add Globalize::Backend::Dummy.new }
37 assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
38 end
39
40 test "accepts a class and instantiates the backend" do
41 assert_nothing_raised { I18n.backend.add Globalize::Backend::Dummy }
42 assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
43 end
44
45 test "accepts a symbol, constantizes test as a backend class and instantiates the backend" do
46 assert_nothing_raised { I18n.backend.add :dummy }
47 assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
48 end
49
50 test "accepts any number of backend instances, classes or symbols" do
51 assert_nothing_raised { I18n.backend.add Globalize::Backend::Dummy.new, Globalize::Backend::Dummy, :dummy }
52 assert_instance_of Globalize::Backend::Dummy, I18n.backend.send(:backends).first
53 assert_equal [ Globalize::Backend::Dummy, Globalize::Backend::Dummy, Globalize::Backend::Dummy ],
54 I18n.backend.send(:backends).map{|backend| backend.class }
55 end
56
57end
58
59class TranslateChainedTest < ActiveSupport::TestCase
60 def setup
61 I18n.backend = Globalize::Backend::Chain.new
62 @first_backend = I18n::Backend::Simple.new
63 @last_backend = I18n::Backend::Simple.new
64 I18n.backend.add @first_backend
65 I18n.backend.add @last_backend
66 end
67
68 test "delegates #translate to all backends in the order they were added" do
69 @first_backend.expects(:translate).with(:en, :foo, {})
70 @last_backend.expects(:translate).with(:en, :foo, {})
71 I18n.translate :foo
72 end
73
74 test "returns the result from #translate from the first backend if test's not nil" do
75 @first_backend.store_translations :en, {:foo => 'foo from first backend'}
76 @last_backend.store_translations :en, {:foo => 'foo from last backend'}
77 result = I18n.translate :foo
78 assert_equal 'foo from first backend', result
79 end
80
81 test "returns the result from #translate from the second backend if the first one returned nil" do
82 @first_backend.store_translations :en, {}
83 @last_backend.store_translations :en, {:foo => 'foo from last backend'}
84 result = I18n.translate :foo
85 assert_equal 'foo from last backend', result
86 end
87
88 test "looks up a namespace from all backends and merges them (if a result is a hash and no count option is present)" do
89 @first_backend.store_translations :en, {:foo => {:bar => 'bar from first backend'}}
90 @last_backend.store_translations :en, {:foo => {:baz => 'baz from last backend'}}
91 result = I18n.translate :foo
92 assert_equal( {:bar => 'bar from first backend', :baz => 'baz from last backend'}, result )
93 end
94
95 test "raises a MissingTranslationData exception if no translation was found" do
96 assert_raise( I18n::MissingTranslationData ) { I18n.translate :not_here, :raise => true }
97 end
98
99 test "raises an InvalidLocale exception if the locale is nil" do
100 assert_raise( I18n::InvalidLocale ) { Globalize::Backend::Chain.new.translate nil, :foo }
101 end
102
103 test "bulk translates a number of keys from different backends" do
104 @first_backend.store_translations :en, {:foo => 'foo from first backend'}
105 @last_backend.store_translations :en, {:bar => 'bar from last backend'}
106 result = I18n.translate [:foo, :bar]
107 assert_equal( ['foo from first backend', 'bar from last backend'], result )
108 end
109
110 test "still calls #translate on all the backends" do
111 @last_backend.expects :translate
112 I18n.translate :not_here, :default => 'default'
113 end
114
115 test "returns a given default string when no backend returns a translation" do
116 result = I18n.translate :not_here, :default => 'default'
117 assert_equal 'default', result
118 end
119
120end
121
122class CustomLocalizeBackend < I18n::Backend::Simple
123 def localize(locale, object, format = :default)
124 "result from custom localize backend" if locale == 'custom'
125 end
126end
127
128class LocalizeChainedTest < ActiveSupport::TestCase
129 def setup
130 I18n.locale = :en
131 I18n.backend = Globalize::Backend::Chain.new
132 @first_backend = CustomLocalizeBackend.new
133 @last_backend = I18n::Backend::Simple.new
134 I18n.backend.add @first_backend
135 I18n.backend.add @last_backend
136 @time = Time.now
137 end
138
139 test "delegates #localize to all backends in the order they were added" do
140 @first_backend.expects(:localize).with(:en, @time, :default)
141 @last_backend.expects(:localize).with(:en, @time, :default)
142 I18n.localize @time
143 end
144
145 test "returns the result from #localize from the first backend if test's not nil" do
146 @last_backend.expects(:localize).never
147 result = I18n.localize @time, :locale => 'custom'
148 assert_equal 'result from custom localize backend', result
149 end
150
151 test "returns the result from #localize from the second backend if the first one returned nil" do
152 @last_backend.expects(:localize).returns "value from last backend"
153 result = I18n.localize @time
154 assert_equal 'value from last backend', result
155 end
156end
157
158class NamespaceChainedTest < ActiveSupport::TestCase
159 def setup
160 @backend = Globalize::Backend::Chain.new
161 end
162
163 test "returns false if the given result is not a Hash" do
164 assert !@backend.send(:namespace_lookup?, 'foo', {})
165 end
166
167 test "returns false if a count option is present" do
168 assert !@backend.send(:namespace_lookup?, {:foo => 'foo'}, {:count => 1})
169 end
170
171 test "returns true if the given result is a Hash AND no count option is present" do
172 assert @backend.send(:namespace_lookup?, {:foo => 'foo'}, {})
173 end
174end
diff --git a/vendor/plugins/globalize2/test/backends/pluralizing_test.rb b/vendor/plugins/globalize2/test/backends/pluralizing_test.rb
new file mode 100644
index 0000000..7445e3f
--- /dev/null
+++ b/vendor/plugins/globalize2/test/backends/pluralizing_test.rb
@@ -0,0 +1,63 @@
1require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2require 'globalize/backend/pluralizing'
3
4class PluralizingTest < ActiveSupport::TestCase
5 def setup
6 @backend = Globalize::Backend::Pluralizing.new
7 @cz_pluralizer = lambda{|c| c == 1 ? :one : (2..4).include?(c) ? :few : :other }
8 end
9
10 test "#pluralizer returns the pluralizer for a given locale if defined" do
11 assert_instance_of Proc, @backend.pluralizer(:en)
12 end
13
14 test "#pluralizer returns the default pluralizer if no pluralizer is defined for the given locale" do
15 assert_equal @backend.pluralizer(:en), @backend.pluralizer(:de)
16 end
17
18 test "#add_pluralizer allows to store a pluralizer per locale" do
19 assert_nothing_raised { @backend.add_pluralizer(:cz, @cz_pluralizer) }
20 assert_equal @cz_pluralizer, @backend.pluralizer(:cz)
21 end
22
23end
24
25class PluralizePluralizingTest < ActiveSupport::TestCase
26 def setup
27 @backend = Globalize::Backend::Pluralizing.new
28 @cz_pluralizer = lambda{|c| c == 1 ? :one : (2..4).include?(c) ? :few : :other }
29 @backend.store_translations :en, :foo => {:one => 'one en foo', :other => 'many en foos'}
30 @backend.store_translations :cz, :foo => {:one => 'one cz foo', :few => 'few cz foos', :other => 'many cz foos'}
31 end
32
33 test "looks up the :one translation when count is 1" do
34 assert_equal 'one en foo', @backend.translate(:en, :foo, :count => 1)
35 end
36
37 test "looks up the :other translation when count is 2" do
38 assert_equal 'many en foos', @backend.translate(:en, :foo, :count => 2)
39 end
40end
41
42class CzPluralizingTest < ActiveSupport::TestCase
43 def setup
44 @backend = Globalize::Backend::Pluralizing.new
45 @cz_pluralizer = lambda{|c| c == 1 ? :one : (2..4).include?(c) ? :few : :other }
46 @backend.store_translations :en, :foo => {:one => 'one en foo', :other => 'many en foos'}
47 @backend.store_translations :cz, :foo => {:one => 'one cz foo', :few => 'few cz foos', :other => 'many cz foos'}
48 @backend.add_pluralizer(:cz, @cz_pluralizer)
49 end
50
51 test "looks up the :one translation when count is 1 (:cz)" do
52 assert_equal 'one cz foo', @backend.translate(:cz, :foo, :count => 1)
53 end
54
55 test "looks up the :few translation when count is 2 (:cz)" do
56 assert_equal 'few cz foos', @backend.translate(:cz, :foo, :count => 2)
57 end
58
59 test "looks up the :other translation when count is 5 (:cz)" do
60 assert_equal 'many cz foos', @backend.translate(:cz, :foo, :count => 5)
61 end
62
63end
diff --git a/vendor/plugins/globalize2/test/backends/static_test.rb b/vendor/plugins/globalize2/test/backends/static_test.rb
new file mode 100644
index 0000000..133e547
--- /dev/null
+++ b/vendor/plugins/globalize2/test/backends/static_test.rb
@@ -0,0 +1,143 @@
1require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2require 'globalize/backend/static'
3require 'globalize/translation'
4require 'action_view'
5include ActionView::Helpers::NumberHelper
6
7I18n.locale = :'en-US' # Need to set this, since I18n defaults to 'en'
8
9class StaticTest < ActiveSupport::TestCase
10 def setup
11 I18n.backend = Globalize::Backend::Static.new
12 translations = {:"en-US" => {:foo => "foo in en-US", :boz => 'boz', :buz => {:bum => 'bum'}},
13 :"en" => {:bar => "bar in en"},
14 :"de-DE" => {:baz => "baz in de-DE"},
15 :"de" => {:boo => "boo in de", :number => { :currency => { :format => { :unit => '€', :format => '%n %u'}}}}}
16 translations.each do |locale, data|
17 I18n.backend.store_translations locale, data
18 end
19 I18n.fallbacks.map :"de-DE" => :"en-US", :he => :en
20 end
21
22 test "returns an instance of Translation:Static" do
23 translation = I18n.translate :foo
24 assert_instance_of Globalize::Translation::Static, translation
25 end
26
27 test "returns the translation in en-US if present" do
28 assert_equal "foo in en-US", I18n.translate(:foo, :locale => :"en-US")
29 end
30
31 test "returns the translation in en if en-US is not present" do
32 assert_equal "bar in en", I18n.translate(:bar, :locale => :"en-US")
33 end
34
35 test "returns the translation in de-DE if present" do
36 assert_equal "baz in de-DE", I18n.translate(:baz, :locale => :"de-DE")
37 end
38
39 test "returns the translation in de if de-DE is not present" do
40 assert_equal "boo in de", I18n.translate(:boo, :locale => :"de-DE")
41 end
42
43 test "returns the translation in en-US if none of de-DE and de are present" do
44 assert_equal "foo in en-US", I18n.translate(:foo, :locale => :"de-DE")
45 end
46
47 test "returns the translation in en if none of de-DE, de and en-US are present" do
48 assert_equal "bar in en", I18n.translate(:bar, :locale => :"de-DE")
49 end
50
51 test "returns the translation in en if none in he is present" do
52 assert_equal "bar in en", I18n.translate(:bar, :locale => :he)
53 end
54
55 test "returns the given default String when the key is not present for any locale" do
56 assert_equal "default", I18n.translate(:missing, :default => "default")
57 end
58
59 test "returns the fallback translation for the key if present for a fallback locale" do
60 I18n.backend.store_translations :de, :non_default => "non_default in de"
61 assert_equal "non_default in de", I18n.translate(:non_default, :default => "default", :locale => :"de-DE")
62 end
63
64 test "returns an array of translations" do
65 assert_instance_of Array, I18n.translate([:foo, :boz])
66 end
67
68 test "returns an array of instances of Translation::Static" do
69 assert_equal [Globalize::Translation::Static], I18n.translate([:foo, :boz]).map(&:class).uniq
70 end
71
72 test "returns a hash of translations" do
73 assert_instance_of Hash, I18n.translate(:"buz")
74 end
75
76 test "returns an array of translations 2" do
77 assert_equal [Globalize::Translation::Static], I18n.translate(:"buz").values.map(&:class)
78 end
79
80 test "returns currency properly formated" do
81 currency = number_to_currency(10)
82 assert_equal "$10.00", currency
83 end
84
85 test "returns currency properly formated for locale" do
86 currency = number_to_currency(10, :locale => :'de')
87 assert_equal "10.000 €", currency
88 end
89
90 test "returns currency properly formated from parameters" do
91 currency = number_to_currency(10, :format => "%n %u", :unit => '€')
92 assert_equal "10.00 €", currency
93 end
94
95 test "makes sure interpolation does not break even with False as string" do
96 assert_equal "translation missing: en, support, array, skip_last_comma", I18n.translate(:"support.array.skip_last_comma")
97 end
98end
99
100class TranslationStaticTest < ActiveSupport::TestCase
101 def setup
102 I18n.backend = Globalize::Backend::Static.new
103 translations = {
104 :greeting => "Hi {{name}}",
105 :messages => { :one => "You have one message.", :other => "You have {{count}} messages."}
106 }
107 I18n.backend.store_translations :"en", translations
108 end
109
110 def greeting
111 I18n.translate :greeting, :locale => :"en-US", :name => "Joshua"
112 end
113
114 test "stores the actual locale" do
115 assert_equal :en, greeting.locale
116 end
117
118 test "stores the requested locale" do
119 assert_equal :'en-US', greeting.requested_locale
120 end
121
122 test "stores the requested key" do
123 assert_equal :greeting, greeting.key
124 end
125
126 test "stores the options given to #translate" do
127 assert_equal( {:name => "Joshua"}, greeting.options )
128 end
129
130 test "stores the original translation before test was interpolated" do
131 assert_equal "Hi {{name}}", greeting.original
132 end
133
134 test "stores the plural_key :one if pluralized as such" do
135 message = I18n.translate :messages, :locale => :"en-US", :count => 1
136 assert_equal :one, message.plural_key
137 end
138
139 test "stores the plural_key :other if pluralized as such" do
140 messages = I18n.translate :messages, :locale => :"en-US", :count => 2
141 assert_equal :other, messages.plural_key
142 end
143end
diff --git a/vendor/plugins/globalize2/test/data/locale/all.yml b/vendor/plugins/globalize2/test/data/locale/all.yml
new file mode 100644
index 0000000..ee4fb4a
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/locale/all.yml
@@ -0,0 +1,2 @@
1en-US:
2 from-all-file: From the "all" file.
diff --git a/vendor/plugins/globalize2/test/data/locale/de-DE.yml b/vendor/plugins/globalize2/test/data/locale/de-DE.yml
new file mode 100644
index 0000000..d4c468e
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/locale/de-DE.yml
@@ -0,0 +1,2 @@
1de-DE:
2 from-locale-file: Aus der Locale Datei. \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/locale/en-US.yml b/vendor/plugins/globalize2/test/data/locale/en-US.yml
new file mode 100644
index 0000000..866b171
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/locale/en-US.yml
@@ -0,0 +1,2 @@
1en-US:
2 from-locale-file: From the locale file.
diff --git a/vendor/plugins/globalize2/test/data/locale/en-US/module.yml b/vendor/plugins/globalize2/test/data/locale/en-US/module.yml
new file mode 100644
index 0000000..6655e9b
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/locale/en-US/module.yml
@@ -0,0 +1,2 @@
1en-US:
2 from-locale-dir: From the locale directory.
diff --git a/vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml b/vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml
new file mode 100644
index 0000000..62d00b1
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/locale/fi-FI/module.yml
@@ -0,0 +1,2 @@
1fi-FI:
2 from-locale-dir: Locale hakemistosta. \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/data/locale/root.yml b/vendor/plugins/globalize2/test/data/locale/root.yml
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/locale/root.yml
diff --git a/vendor/plugins/globalize2/test/data/no_globalize_schema.rb b/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
new file mode 100644
index 0000000..7cfaf69
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/no_globalize_schema.rb
@@ -0,0 +1,11 @@
1# This schema creates tables without columns for the translated fields
2ActiveRecord::Schema.define do
3 create_table :blogs, :force => true do |t|
4 t.string :name
5 end
6
7 create_table :posts, :force => true do |t|
8 t.references :blog
9 end
10end
11
diff --git a/vendor/plugins/globalize2/test/data/post.rb b/vendor/plugins/globalize2/test/data/post.rb
new file mode 100644
index 0000000..20a2495
--- /dev/null
+++ b/vendor/plugins/globalize2/test/data/post.rb
@@ -0,0 +1,8 @@
1class Post < ActiveRecord::Base
2 translates :subject, :content
3 validates_presence_of :subject
4end
5
6class Blog < ActiveRecord::Base
7 has_many :posts, :order => 'id ASC'
8end
diff --git a/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb b/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
new file mode 100644
index 0000000..8641d57
--- /dev/null
+++ b/vendor/plugins/globalize2/test/i18n/missing_translations_test.rb
@@ -0,0 +1,36 @@
1require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2require 'globalize/i18n/missing_translations_log_handler'
3
4class MissingTranslationsTest < ActiveSupport::TestCase
5 test "defines I18n.missing_translations_logger accessor" do
6 assert I18n.respond_to?(:missing_translations_logger)
7 end
8
9 test "defines I18n.missing_translations_logger= writer" do
10 assert I18n.respond_to?(:missing_translations_logger=)
11 end
12end
13
14class TestLogger < String
15 def warn(msg) self.concat msg; end
16end
17
18class LogMissingTranslationsTest < ActiveSupport::TestCase
19 def setup
20 @locale, @key, @options = :en, :foo, {}
21 @exception = I18n::MissingTranslationData.new(@locale, @key, @options)
22
23 @logger = TestLogger.new
24 I18n.missing_translations_logger = @logger
25 end
26
27 test "still returns the exception message for MissingTranslationData exceptions" do
28 result = I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
29 assert_equal 'translation missing: en, foo', result
30 end
31
32 test "logs the missing translation to I18n.missing_translations_logger" do
33 I18n.send(:missing_translations_log_handler, @exception, @locale, @key, @options)
34 assert_equal 'translation missing: en, foo', @logger
35 end
36end
diff --git a/vendor/plugins/globalize2/test/load_path_test.rb b/vendor/plugins/globalize2/test/load_path_test.rb
new file mode 100644
index 0000000..ff009b3
--- /dev/null
+++ b/vendor/plugins/globalize2/test/load_path_test.rb
@@ -0,0 +1,49 @@
1require File.join( File.dirname(__FILE__), 'test_helper' )
2require 'globalize/load_path'
3
4class LoadPathTest < ActiveSupport::TestCase
5 def setup
6 @plugin_dir = "#{File.dirname(__FILE__)}/.."
7 @locale_dir = "#{File.dirname(__FILE__)}/data/locale"
8 @load_path = Globalize::LoadPath.new
9 end
10
11 test "returns glob patterns for all locales and ruby + yaml files by default" do
12 patterns = %w(locales/all.rb
13 locales/*.rb
14 locales/*/**/*.rb
15 locales/all.yml
16 locales/*.yml
17 locales/*/**/*.yml)
18 assert_equal patterns, @load_path.send(:patterns, 'locales')
19 end
20
21 test "returns the glob patterns for registered locales and extensions" do
22 @load_path.locales = [:en, :de]
23 @load_path.extensions = [:sql]
24 patterns = %w(locales/all.sql
25 locales/en.sql
26 locales/en/**/*.sql
27 locales/de.sql
28 locales/de/**/*.sql)
29 assert_equal patterns, @load_path.send(:patterns, 'locales')
30 end
31
32 test "expands paths using yml as a default file extension" do
33 @load_path << @locale_dir
34 expected = %w(all.yml de-DE.yml en-US.yml en-US/module.yml fi-FI/module.yml root.yml)
35 assert_equal expected, @load_path.map{|path| path.sub("#{@locale_dir}\/", '')}
36 end
37
38 test "appends new paths to the collection so earlier collected paths preceed later collected ones" do
39 @load_path.locales = [:root]
40 @load_path << "#{@plugin_dir}/lib/locale"
41 @load_path << @locale_dir
42
43 expected = %W(#{@plugin_dir}/lib/locale/root.yml
44 #{@locale_dir}/all.yml
45 #{@locale_dir}/root.yml)
46 assert_equal expected, @load_path
47 end
48
49end
diff --git a/vendor/plugins/globalize2/test/locale/fallbacks_test.rb b/vendor/plugins/globalize2/test/locale/fallbacks_test.rb
new file mode 100644
index 0000000..304d3da
--- /dev/null
+++ b/vendor/plugins/globalize2/test/locale/fallbacks_test.rb
@@ -0,0 +1,154 @@
1require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2require 'globalize/locale/fallbacks'
3
4include Globalize::Locale
5I18n.default_locale = :'en-US' # This has to be set explicitly, no longer default for I18n
6
7class FallbacksTest < ActiveSupport::TestCase
8 def setup
9 I18n.fallbacks = Fallbacks.new
10 end
11
12 def teardown
13 I18n.default_locale = :'en-US'
14 end
15
16 test "#[] caches computed results" do
17 I18n.fallbacks['en']
18 assert_equal( { :en => [:en, :"en-US", :root] }, I18n.fallbacks )
19 end
20
21 test "#defaults always reflect the I18n.default_locale if no default has been set manually" do
22 I18n.default_locale = :'en-US'
23 assert_equal( [:'en-US', :en, :root], I18n.fallbacks.defaults )
24 end
25
26 test "#defaults always reflect a manually passed default locale if any" do
27 I18n.fallbacks = Fallbacks.new(:'fi-FI')
28 assert_equal( [:'fi-FI', :fi, :root], I18n.fallbacks.defaults )
29 I18n.default_locale = :'de-DE'
30 assert_equal( [:'fi-FI', :fi, :root], I18n.fallbacks.defaults )
31 end
32
33 test "#defaults allows to set multiple defaults" do
34 I18n.fallbacks = Fallbacks.new(:'fi-FI', :'se-FI')
35 assert_equal( [:'fi-FI', :fi, :'se-FI', :se, :root], I18n.fallbacks.defaults )
36 end
37end
38
39class NoMappingFallbacksTest < ActiveSupport::TestCase
40 def setup
41 @fallbacks = Fallbacks.new(:'en-US')
42 end
43
44 test "returns [:es, :en-US, :root] for :es" do
45 assert_equal [:es, :"en-US", :en, :root], @fallbacks[:es]
46 end
47
48 test "returns [:es-ES, :es, :en-US, :root] for :es-ES" do
49 assert_equal [:"es-ES", :es, :"en-US", :en, :root], @fallbacks[:"es-ES"]
50 end
51
52 test "returns [:es-MX, :es, :en-US, :root] for :es-MX" do
53 assert_equal [:"es-MX", :es, :"en-US", :en, :root], @fallbacks[:"es-MX"]
54 end
55
56 test "returns [:es-Latn-ES, :es-Latn, :es, :en-US, :root] for :es-Latn-ES" do
57 assert_equal [:"es-Latn-ES", :"es-Latn", :es, :"en-US", :en, :root], @fallbacks[:'es-Latn-ES']
58 end
59
60 test "returns [:en, :en-US, :root] for :en" do
61 assert_equal [:en, :"en-US", :root], @fallbacks[:en]
62 end
63
64 test "returns [:en-US, :en, :root] for :en-US (special case: locale == default)" do
65 assert_equal [:"en-US", :en, :root], @fallbacks[:"en-US"]
66 end
67end
68
69class CaMappingFallbacksTest < ActiveSupport::TestCase
70 # Most people who speak Catalan also live in Spain, so test is safe to assume
71 # that they also speak Spanish as spoken in Spain.
72 def setup
73 @fallbacks = Fallbacks.new(:'en-US')
74 @fallbacks.map :ca => :"es-ES"
75 end
76
77 test "returns [:ca, :es-ES, :es, :en-US, :root] for :ca" do
78 assert_equal [:ca, :"es-ES", :es, :"en-US", :en, :root], @fallbacks[:ca]
79 end
80
81 test "returns [:ca-ES, :ca, :es-ES, :es, :en-US, :root] for :ca-ES" do
82 assert_equal [:"ca-ES", :ca, :"es-ES", :es, :"en-US", :en, :root], @fallbacks[:"ca-ES"]
83 end
84end
85
86class ArMappingFallbacksTest < ActiveSupport::TestCase
87 # People who speak Arabic as spoken in Palestine often times also speak
88 # Hebrew as spoken in Israel. However test is in no way safe to assume that
89 # everybody who speaks Arabic also speaks Hebrew.
90 def setup
91 @fallbacks = Fallbacks.new(:'en-US')
92 @fallbacks.map :"ar-PS" => :"he-IL"
93 end
94
95 test "returns [:ar, :en-US, :root] for :ar" do
96 assert_equal [:ar, :"en-US", :en, :root], @fallbacks[:ar]
97 end
98
99 test "returns [:ar-EG, :ar, :en-US, :root] for :ar-EG" do
100 assert_equal [:"ar-EG", :ar, :"en-US", :en, :root], @fallbacks[:"ar-EG"]
101 end
102
103 test "returns [:ar-PS, :ar, :he-IL, :he, :en-US, :root] for :ar-PS" do
104 assert_equal [:"ar-PS", :ar, :"he-IL", :he, :"en-US", :en, :root], @fallbacks[:"ar-PS"]
105 end
106end
107
108class SmsMappingFallbacksTest < ActiveSupport::TestCase
109 # Sami people live in several scandinavian countries. In Finnland many people
110 # know Swedish and Finnish. Thus, test can be assumed that Sami living in
111 # Finnland also speak Swedish and Finnish.
112 def setup
113 @fallbacks = Fallbacks.new(:'en-US')
114 @fallbacks.map :sms => [:"se-FI", :"fi-FI"]
115 end
116
117 test "returns [:sms-FI, :sms, :se-FI, :se, :fi-FI, :fi, :en-US, :root] for :sms-FI" do
118 assert_equal [:"sms-FI", :sms, :"se-FI", :se, :"fi-FI", :fi, :"en-US", :en, :root], @fallbacks[:"sms-FI"]
119 end
120end
121
122class DeAtMappingFallbacksTest < ActiveSupport::TestCase
123 def setup
124 @fallbacks = Fallbacks.new(:'en-US')
125 @fallbacks.map :"de-AT" => :"de-DE"
126 end
127
128 test "returns [:de, :en-US, :root] for de" do
129 assert_equal [:de, :"en-US", :en, :root], @fallbacks[:"de"]
130 end
131
132 test "returns [:de-DE, :de, :en-US, :root] for de-DE" do
133 assert_equal [:"de-DE", :de, :"en-US", :en, :root], @fallbacks[:"de-DE"]
134 end
135
136 test "returns [:de-AT, :de, :de-DE, :en-US, :root] for de-AT" do
137 assert_equal [:"de-AT", :de, :"de-DE", :"en-US", :en, :root], @fallbacks[:"de-AT"]
138 end
139end
140
141class DeMappingFallbacksTest < ActiveSupport::TestCase
142 def setup
143 @fallbacks = Fallbacks.new(:'en-US')
144 @fallbacks.map :de => :en, :he => :en
145 end
146
147 test "returns [:de, :en, :root] for :de" do
148 assert_equal [:de, :en, :"en-US", :root], @fallbacks[:de]
149 end
150
151 test "returns [:he, :en, :root] for :de" do
152 assert_equal [:he, :en, :"en-US", :root], @fallbacks[:he]
153 end
154end
diff --git a/vendor/plugins/globalize2/test/locale/language_tag_test.rb b/vendor/plugins/globalize2/test/locale/language_tag_test.rb
new file mode 100644
index 0000000..2448af1
--- /dev/null
+++ b/vendor/plugins/globalize2/test/locale/language_tag_test.rb
@@ -0,0 +1,130 @@
1require File.join( File.dirname(__FILE__), '..', 'test_helper' )
2require 'globalize/locale/language_tag'
3
4include Globalize::Locale
5
6class LanguageTagTest < ActiveSupport::TestCase
7 test "given a valid tag 'de' returns an LanguageTag from #tag" do
8 assert_instance_of LanguageTag, LanguageTag.tag('de')
9 end
10
11 test "given a valid tag 'de' returns an array of subtags" do
12 assert_equal ['de', nil, nil, nil, nil, nil, nil], LanguageTag::SimpleParser.match('de')
13 end
14
15 test "given a valid tag 'de-DE' returns an array of subtags" do
16 assert_equal ['de', nil, 'DE', nil, nil, nil, nil], LanguageTag::SimpleParser.match('de-DE')
17 end
18
19 test "given a valid lowercase tag 'de-latn-de-variant-x-phonebk' returns an array of subtags" do
20 assert_equal ['de', 'latn', 'de', 'variant', nil, 'x-phonebk', nil],
21 LanguageTag::SimpleParser.match('de-latn-de-variant-x-phonebk')
22 end
23
24 test "given a valid uppercase tag 'DE-LATN-DE-VARIANT-X-PHONEBK' returns an array of subtags" do
25 assert_equal ['DE', 'LATN', 'DE', 'VARIANT', nil, 'X-PHONEBK', nil],
26 LanguageTag::SimpleParser.match('DE-LATN-DE-VARIANT-X-PHONEBK')
27 end
28
29 test "given an invalid tag 'a-DE' test returns false" do
30 assert !LanguageTag::SimpleParser.match('a-DE')
31 end
32
33 test "given an invalid tag 'de-419-DE' test returns false" do
34 assert !LanguageTag::SimpleParser.match('de-419-DE')
35 end
36end
37
38class DeLatnLanguageTagTest < ActiveSupport::TestCase
39 def setup
40 subtags = %w(de Latn DE variant a-ext x-phonebk i-klingon)
41 @tag = LanguageTag.new *subtags
42 end
43
44 test "returns 'de' as the language subtag in lowercase" do
45 assert_equal 'de', @tag.language
46 end
47
48 test "returns 'Latn' as the script subtag in titlecase" do
49 assert_equal 'Latn', @tag.script
50 end
51
52 test "returns 'DE' as the region subtag in uppercase" do
53 assert_equal 'DE', @tag.region
54 end
55
56 test "returns 'variant' as the variant subtag in lowercase" do
57 assert_equal 'variant', @tag.variant
58 end
59
60 test "returns 'a-ext' as the extension subtag" do
61 assert_equal 'a-ext', @tag.extension
62 end
63
64 test "returns 'x-phonebk' as the privateuse subtag" do
65 assert_equal 'x-phonebk', @tag.privateuse
66 end
67
68 test "returns 'i-klingon' as the grandfathered subtag" do
69 assert_equal 'i-klingon', @tag.grandfathered
70 end
71
72 test "returns a formatted tag string from #to_s" do
73 assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon', @tag.to_s
74 end
75
76 test "returns an array containing the formatted subtags from #to_a" do
77 assert_equal %w(de Latn DE variant a-ext x-phonebk i-klingon), @tag.to_a
78 end
79end
80
81class InheritanceLanguageTagTest < ActiveSupport::TestCase
82 test "returns 'de-Latn-DE-variant-a-ext-x-phonebk' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
83 tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
84 assert_equal 'de-Latn-DE-variant-a-ext-x-phonebk', tag.parent.to_s
85 end
86
87 test "returns 'de-Latn-DE-variant-a-ext' as the parent of 'de-Latn-DE-variant-a-ext-x-phonebk'" do
88 tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk)
89 assert_equal 'de-Latn-DE-variant-a-ext', tag.parent.to_s
90 end
91
92 test "returns 'de-Latn-DE-variant' as the parent of 'de-Latn-DE-variant-a-ext'" do
93 tag = LanguageTag.new *%w(de Latn DE variant a-ext)
94 assert_equal 'de-Latn-DE-variant', tag.parent.to_s
95 end
96
97 test "returns 'de-Latn-DE' as the parent of 'de-Latn-DE-variant'" do
98 tag = LanguageTag.new *%w(de Latn DE variant)
99 assert_equal 'de-Latn-DE', tag.parent.to_s
100 end
101
102 test "returns 'de-Latn' as the parent of 'de-Latn-DE'" do
103 tag = LanguageTag.new *%w(de Latn DE)
104 assert_equal 'de-Latn', tag.parent.to_s
105 end
106
107 test "returns 'de' as the parent of 'de-Latn'" do
108 tag = LanguageTag.new *%w(de Latn)
109 assert_equal 'de', tag.parent.to_s
110 end
111
112 # TODO RFC4647 says: "If no language tag matches the request, the "default" value is returned."
113 # where should we set the default language?
114 # test "returns '' as the parent of 'de'" do
115 # tag = LanguageTag.new *%w(de)
116 # assert_equal '', tag.parent.to_s
117 # end
118
119 test "returns an array of 5 parents for 'de-Latn-DE-variant-a-ext-x-phonebk-i-klingon'" do
120 parents = %w(de-Latn-DE-variant-a-ext-x-phonebk-i-klingon
121 de-Latn-DE-variant-a-ext-x-phonebk
122 de-Latn-DE-variant-a-ext
123 de-Latn-DE-variant
124 de-Latn-DE
125 de-Latn
126 de)
127 tag = LanguageTag.new *%w(de Latn DE variant a-ext x-phonebk i-klingon)
128 assert_equal parents, tag.parents.map{|tag| tag.to_s}
129 end
130end
diff --git a/vendor/plugins/globalize2/test/model/active_record/migration_test.rb b/vendor/plugins/globalize2/test/model/active_record/migration_test.rb
new file mode 100644
index 0000000..09804c7
--- /dev/null
+++ b/vendor/plugins/globalize2/test/model/active_record/migration_test.rb
@@ -0,0 +1,73 @@
1require File.join( File.dirname(__FILE__), '..', '..', 'test_helper' )
2require 'active_record'
3require 'globalize/model/active_record'
4
5# Hook up model translation
6ActiveRecord::Base.send(:include, Globalize::Model::ActiveRecord::Translated)
7
8# Load Post model
9require File.join( File.dirname(__FILE__), '..', '..', 'data', 'post' )
10
11class MigrationTest < ActiveSupport::TestCase
12 def setup
13 reset_db! 'no_globalize_schema'
14 end
15
16 test 'globalize table added' do
17 assert !Post.connection.table_exists?( :post_translations )
18 Post.create_translation_table! :subject => :string, :content => :text
19 assert Post.connection.table_exists?( :post_translations )
20 columns = Post.connection.columns( :post_translations )
21 assert locale = columns.detect {|c| c.name == 'locale' }
22 assert_equal :string, locale.type
23 assert subject = columns.detect {|c| c.name == 'subject' }
24 assert_equal :string, subject.type
25 assert content = columns.detect {|c| c.name == 'content' }
26 assert_equal :text, content.type
27 assert post_id = columns.detect {|c| c.name == 'post_id' }
28 assert_equal :integer, post_id.type
29 assert created_at = columns.detect {|c| c.name == 'created_at' }
30 assert_equal :datetime, created_at.type
31 assert updated_at = columns.detect {|c| c.name == 'updated_at' }
32 assert_equal :datetime, updated_at.type
33 end
34
35 test 'globalize table dropped' do
36 assert !Post.connection.table_exists?( :post_translations )
37 Post.create_translation_table! :subject => :string, :content => :text
38 assert Post.connection.table_exists?( :post_translations )
39 Post.drop_translation_table!
40 assert !Post.connection.table_exists?( :post_translations )
41 end
42
43 test 'exception on untranslated field inputs' do
44 assert_raise Globalize::Model::UntranslatedMigrationField do
45 Post.create_translation_table! :subject => :string, :content => :text, :bogus => :string
46 end
47 end
48
49 test 'exception on missing field inputs' do
50 assert_raise Globalize::Model::MigrationMissingTranslatedField do
51 Post.create_translation_table! :content => :text
52 end
53 end
54
55 test 'exception on bad input type' do
56 assert_raise Globalize::Model::BadMigrationFieldType do
57 Post.create_translation_table! :subject => :string, :content => :integer
58 end
59 end
60
61 test 'create_translation_table! should not be called on non-translated models' do
62 assert_raise NoMethodError do
63 Blog.create_translation_table! :name => :string
64 end
65 end
66
67 test 'drop_translation_table! should not be called on non-translated models' do
68 assert_raise NoMethodError do
69 Blog.drop_translation_table!
70 end
71 end
72
73end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/model/active_record/translated_test.rb b/vendor/plugins/globalize2/test/model/active_record/translated_test.rb
new file mode 100644
index 0000000..ec507e0
--- /dev/null
+++ b/vendor/plugins/globalize2/test/model/active_record/translated_test.rb
@@ -0,0 +1,266 @@
1require File.join( File.dirname(__FILE__), '..', '..', 'test_helper' )
2require 'active_record'
3require 'globalize/model/active_record'
4
5# Hook up model translation
6ActiveRecord::Base.send(:include, Globalize::Model::ActiveRecord::Translated)
7
8# Load Post model
9require File.join( File.dirname(__FILE__), '..', '..', 'data', 'post' )
10
11class TranslatedTest < ActiveSupport::TestCase
12 def setup
13 I18n.locale = :'en-US'
14 I18n.fallbacks.clear
15 reset_db!
16 end
17
18 def teardown
19 I18n.fallbacks.clear
20 end
21
22 test "modifiying translated fields" do
23 post = Post.create :subject => 'foo'
24 assert_equal 'foo', post.subject
25 post.subject = 'bar'
26 assert_equal 'bar', post.subject
27 end
28
29 test "modifiying translated fields while switching locales" do
30 post = Post.create :subject => 'foo'
31 assert_equal 'foo', post.subject
32 I18n.locale = :'de-DE'
33 post.subject = 'bar'
34 assert_equal 'bar', post.subject
35 I18n.locale = :'en-US'
36 assert_equal 'foo', post.subject
37 I18n.locale = :'de-DE'
38 post.subject = 'bar'
39 end
40
41 test "has post_translations" do
42 post = Post.create
43 assert_nothing_raised { post.globalize_translations }
44 end
45
46 test "has German post_translations" do
47 I18n.locale = :de
48 post = Post.create :subject => 'foo'
49 assert_equal 1, post.globalize_translations.size
50 I18n.locale = :en
51 assert_equal 1, post.globalize_translations.size
52 end
53
54 test "returns the value passed to :subject" do
55 post = Post.new
56 assert_equal 'foo', (post.subject = 'foo')
57 end
58
59 test "translates subject and content into en-US" do
60 post = Post.create :subject => 'foo', :content => 'bar'
61 assert_equal 'foo', post.subject
62 assert_equal 'bar', post.content
63 assert post.save
64 post.reload
65 assert_equal 'foo', post.subject
66 assert_equal 'bar', post.content
67 end
68
69 test "finds a German post" do
70 post = Post.create :subject => 'foo (en)', :content => 'bar'
71 I18n.locale = 'de-DE'
72 post = Post.first
73 post.subject = 'baz (de)'
74 post.save
75 assert_equal 'baz (de)', Post.first.subject
76 I18n.locale = :'en-US'
77 assert_equal 'foo (en)', Post.first.subject
78 end
79
80 test "saves an English post and loads test correctly" do
81 assert_nil Post.first
82 post = Post.create :subject => 'foo', :content => 'bar'
83 assert post.save
84 post = Post.first
85 assert_equal 'foo', post.subject
86 assert_equal 'bar', post.content
87 end
88
89 test "updates an attribute" do
90 post = Post.create :subject => 'foo', :content => 'bar'
91 post.update_attribute :subject, 'baz'
92 assert_equal 'baz', Post.first.subject
93 end
94
95 test "validates presence of :subject" do
96 post = Post.new
97 assert !post.save
98
99 post = Post.new :subject => 'foo'
100 assert post.save
101 end
102
103 test "returns the value for the correct locale, after locale switching" do
104 post = Post.create :subject => 'foo'
105 I18n.locale = 'de-DE'
106 post.subject = 'bar'
107 post.save
108 I18n.locale = 'en-US'
109 post = Post.first
110 assert_equal 'foo', post.subject
111 I18n.locale = 'de-DE'
112 assert_equal 'bar', post.subject
113 end
114
115 test "keeping one field in new locale when other field is changed" do
116 I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
117 post = Post.create :subject => 'foo'
118 I18n.locale = 'de-DE'
119 post.content = 'bar'
120 assert_equal 'foo', post.subject
121 end
122
123 test "modifying non-required field in a new locale" do
124 I18n.fallbacks.map 'de-DE' => [ 'en-US' ]
125 post = Post.create :subject => 'foo'
126 I18n.locale = 'de-DE'
127 post.content = 'bar'
128 assert post.save
129 end
130
131 test "returns the value for the correct locale, after locale switching, without saving" do
132 post = Post.create :subject => 'foo'
133 I18n.locale = 'de-DE'
134 post.subject = 'bar'
135 I18n.locale = 'en-US'
136 assert_equal 'foo', post.subject
137 I18n.locale = 'de-DE'
138 assert_equal 'bar', post.subject
139 end
140
141 test "saves all locales, even after locale switching" do
142 post = Post.new :subject => 'foo'
143 I18n.locale = 'de-DE'
144 post.subject = 'bar'
145 I18n.locale = 'he-IL'
146 post.subject = 'baz'
147 post.save
148 I18n.locale = 'en-US'
149 post = Post.first
150 assert_equal 'foo', post.subject
151 I18n.locale = 'de-DE'
152 assert_equal 'bar', post.subject
153 I18n.locale = 'he-IL'
154 assert_equal 'baz', post.subject
155 end
156
157 test "resolves a simple fallback" do
158 I18n.locale = 'de-DE'
159 post = Post.create :subject => 'foo'
160 I18n.locale = 'de'
161 post.subject = 'baz'
162 post.content = 'bar'
163 post.save
164 I18n.locale = 'de-DE'
165 assert_equal 'foo', post.subject
166 assert_equal 'bar', post.content
167 end
168
169 test "resolves a simple fallback without reloading" do
170 I18n.locale = 'de-DE'
171 post = Post.new :subject => 'foo'
172 I18n.locale = 'de'
173 post.subject = 'baz'
174 post.content = 'bar'
175 I18n.locale = 'de-DE'
176 assert_equal 'foo', post.subject
177 assert_equal 'bar', post.content
178 end
179
180 test "resolves a complex fallback without reloading" do
181 I18n.fallbacks.map 'de' => %w(en he)
182 I18n.locale = 'de'
183 post = Post.new
184 I18n.locale = 'en'
185 post.subject = 'foo'
186 I18n.locale = 'he'
187 post.subject = 'baz'
188 post.content = 'bar'
189 I18n.locale = 'de'
190 assert_equal 'foo', post.subject
191 assert_equal 'bar', post.content
192 end
193
194 test "returns nil if no translations are found" do
195 post = Post.new :subject => 'foo'
196 assert_equal 'foo', post.subject
197 assert_nil post.content
198 end
199
200 test "returns nil if no translations are found; reloaded" do
201 post = Post.create :subject => 'foo'
202 post = Post.first
203 assert_equal 'foo', post.subject
204 assert_nil post.content
205 end
206
207 test "works with associations" do
208 blog = Blog.create
209 post1 = blog.posts.create :subject => 'foo'
210 I18n.locale = 'de-DE'
211 post2 = blog.posts.create :subject => 'bar'
212 assert_equal 2, blog.posts.size
213 I18n.locale = 'en-US'
214 assert_equal 'foo', blog.posts.first.subject
215 assert_nil blog.posts.last.subject
216 I18n.locale = 'de-DE'
217 assert_equal 'bar', blog.posts.last.subject
218 end
219
220 test "works with simple dynamic finders" do
221 foo = Post.create :subject => 'foo'
222 Post.create :subject => 'bar'
223 post = Post.find_by_subject('foo')
224 assert_equal foo, post
225 end
226
227 test 'change attribute on globalized model' do
228 post = Post.create :subject => 'foo', :content => 'bar'
229 assert_equal [], post.changed
230 post.subject = 'baz'
231 assert_equal [ 'subject' ], post.changed
232 post.content = 'quux'
233 assert_member 'subject', post.changed
234 assert_member 'content', post.changed
235 end
236
237 test 'change attribute on globalized model after locale switching' do
238 post = Post.create :subject => 'foo', :content => 'bar'
239 assert_equal [], post.changed
240 post.subject = 'baz'
241 I18n.locale = :de
242 assert_equal [ 'subject' ], post.changed
243 end
244
245 test 'fallbacks with lots of locale switching' do
246 I18n.fallbacks.map :'de-DE' => [ :'en-US' ]
247 post = Post.create :subject => 'foo'
248
249 I18n.locale = :'de-DE'
250 assert_equal 'foo', post.subject
251
252 I18n.locale = :'en-US'
253 post.update_attribute :subject, 'bar'
254
255 I18n.locale = :'de-DE'
256 assert_equal 'bar', post.subject
257 end
258end
259
260# TODO should validate_presence_of take fallbacks into account? maybe we need
261# an extra validation call, or more options for validate_presence_of.
262# TODO error checking for fields that exist in main table, don't exist in
263# proxy table, aren't strings or text
264#
265# TODO allow finding by translated attributes in conditions?
266# TODO generate advanced dynamic finders?
diff --git a/vendor/plugins/globalize2/test/test_helper.rb b/vendor/plugins/globalize2/test/test_helper.rb
new file mode 100644
index 0000000..58b047d
--- /dev/null
+++ b/vendor/plugins/globalize2/test/test_helper.rb
@@ -0,0 +1,26 @@
1require 'rubygems'
2require 'test/unit'
3require 'active_support'
4require 'active_support/test_case'
5require 'mocha'
6
7$LOAD_PATH << File.expand_path( File.dirname(__FILE__) + '/../lib' )
8
9class ActiveSupport::TestCase
10 def reset_db!( schema = 'schema' )
11 ::ActiveRecord::Migration.verbose = false # Quiet down the migration engine
12 ::ActiveRecord::Base.establish_connection({
13 :adapter => 'sqlite3',
14 :dbfile => ':memory:'
15 })
16 ::ActiveRecord::Base.silence do
17 load File.expand_path(File.join(File.dirname(__FILE__), 'data', schema + '.rb'))
18 end
19 end
20
21 def assert_member(item, arr)
22 assert_block "Item #{item} is not in array #{arr}" do
23 arr.member? item
24 end
25 end
26end \ No newline at end of file
diff --git a/vendor/plugins/globalize2/test/translation_test.rb b/vendor/plugins/globalize2/test/translation_test.rb
new file mode 100644
index 0000000..4b52bb1
--- /dev/null
+++ b/vendor/plugins/globalize2/test/translation_test.rb
@@ -0,0 +1,54 @@
1require File.join( File.dirname(__FILE__), 'test_helper' )
2require 'globalize/translation'
3
4class TranslationTest < ActiveSupport::TestCase
5 include Globalize
6
7 def setup
8 @translation = Translation::Static.new 'foo', :locale => :'en-US'
9 end
10
11 test "responds to fallback?" do
12 assert @translation.respond_to?( :fallback? )
13 end
14
15 test "returns true when :locale and :requested_locale are not equal" do
16 @translation.requested_locale = :'de-DE'
17 assert @translation.fallback?
18 end
19
20 test "returns false when :locale and :requested_locale are equal" do
21 @translation.requested_locale = :'en-US'
22 assert !@translation.fallback?
23 end
24
25 test "has the attribute :locale" do
26 assert @translation.respond_to?( :locale )
27 end
28
29 test "has the attribute :requested_locale" do
30 assert @translation.respond_to?( :requested_locale )
31 end
32
33 test "has the attribute :options" do
34 assert @translation.respond_to?( :options )
35 end
36
37 test "has the attribute :plural_key" do
38 assert @translation.respond_to?( :plural_key )
39 end
40
41 test "has the attribute :original" do
42 assert @translation.respond_to?( :original )
43 end
44
45 test "Translation::Attribute has the attribute :locale" do
46 translation = Translation::Attribute.new 'foo'
47 assert translation.respond_to?( :locale )
48 end
49
50 test "Translation::Attribute has the attribute :requested_locale" do
51 translation = Translation::Attribute.new 'foo'
52 assert translation.respond_to?( :requested_locale )
53 end
54end