arena-i18n-active_record 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ Copyright (c) 2010 Sven Fuchs <svenfuchs@artweb-design.de>
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
+
@@ -0,0 +1,72 @@
1
+ h1. I18n::Backend::ActiveRecord
2
+
3
+ This repository contains the I18n ActiveRecord backend and support code that has been extracted from the "I18n":http://github.com/svenfuchs/i18n.
4
+
5
+ h2. Installation
6
+
7
+ For Bundler put the following in your Gemfile:
8
+
9
+ <pre>
10
+ gem 'i18n-active_record',
11
+ :git => 'git://github.com/svenfuchs/i18n-active_record.git',
12
+ :require => 'i18n/active_record'
13
+ </pre>
14
+
15
+ Next create a active record model named @Translation@ with the Rails Generator.
16
+ Your migration should look like this:
17
+
18
+ <pre>
19
+ class CreateTranslations < ActiveRecord::Migration
20
+ def self.up
21
+ create_table :translations do |t|
22
+ t.string :locale
23
+ t.string :key
24
+ t.text :value
25
+ t.text :interpolations
26
+ t.boolean :is_proc, :default => false
27
+
28
+ t.timestamps
29
+ end
30
+ end
31
+
32
+ def self.down
33
+ drop_table :translations
34
+ end
35
+ end
36
+ </pre>
37
+
38
+ With this translation model you will be able to manage your translation, and add new translations or languages through
39
+ it.
40
+
41
+ To load @I18n::Backend::ActiveRecord@ into your Rails application, create a new file in *config/initializers* named *locale.rb*.
42
+
43
+ A simple configuration for your locale.rb could look like this:
44
+
45
+ <pre>
46
+ require 'i18n/backend/active_record'
47
+ I18n.backend = I18n::Backend::ActiveRecord.new
48
+ </pre>
49
+
50
+ A more adavanced example (Thanks Moritz), which uses YAML files and ActiveRecord for lookups:
51
+
52
+ <pre>
53
+ require 'i18n/backend/active_record'
54
+ I18n.backend = I18n::Backend::ActiveRecord.new
55
+
56
+ I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Memoize)
57
+ I18n::Backend::ActiveRecord.send(:include, I18n::Backend::Flatten)
58
+ I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
59
+ I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
60
+
61
+ I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n.backend)
62
+ </pre>
63
+
64
+ h2. Usage
65
+
66
+ You can now use @I18n.t('Your String')@ to lookup translations in the database.
67
+
68
+ h2. Maintainers
69
+
70
+ * Sven Fuchs
71
+
72
+
@@ -0,0 +1,10 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+
4
+ Rake::TestTask.new do |t|
5
+ t.libs << 'lib'
6
+ t.pattern = 'test/**/*_test.rb'
7
+ t.verbose = false
8
+ end
9
+
10
+ task :default => :test
@@ -0,0 +1,10 @@
1
+ source :rubygems
2
+
3
+ # gem 'i18n', '~> 0.5.0'
4
+ gem 'i18n', :path => '~/Development/projects/i18n/i18n'
5
+
6
+ gem 'activerecord', '~> 3.0.0'
7
+ gem 'activesupport', '~> 3.0.0'
8
+ gem 'sqlite3-ruby'
9
+ gem 'mocha'
10
+
@@ -0,0 +1,36 @@
1
+ PATH
2
+ remote: ~/Development/projects/i18n/i18n
3
+ specs:
4
+ i18n (0.4.2)
5
+
6
+ GEM
7
+ remote: http://rubygems.org/
8
+ specs:
9
+ activemodel (3.0.1)
10
+ activesupport (= 3.0.1)
11
+ builder (~> 2.1.2)
12
+ i18n (~> 0.4.1)
13
+ activerecord (3.0.1)
14
+ activemodel (= 3.0.1)
15
+ activesupport (= 3.0.1)
16
+ arel (~> 1.0.0)
17
+ tzinfo (~> 0.3.23)
18
+ activesupport (3.0.1)
19
+ arel (1.0.1)
20
+ activesupport (~> 3.0.0)
21
+ builder (2.1.2)
22
+ mocha (0.9.9)
23
+ rake
24
+ rake (0.8.7)
25
+ sqlite3-ruby (1.3.1)
26
+ tzinfo (0.3.23)
27
+
28
+ PLATFORMS
29
+ ruby
30
+
31
+ DEPENDENCIES
32
+ activerecord (~> 3.0.0)
33
+ activesupport (~> 3.0.0)
34
+ i18n!
35
+ mocha
36
+ sqlite3-ruby
@@ -0,0 +1 @@
1
+ require 'i18n'
@@ -0,0 +1,6 @@
1
+ module I18n
2
+ module ActiveRecord
3
+ VERSION = "0.0.4"
4
+ end
5
+ end
6
+
@@ -0,0 +1,62 @@
1
+ require 'i18n/backend/base'
2
+ require 'i18n/backend/active_record/translation'
3
+
4
+ module I18n
5
+ module Backend
6
+ class ActiveRecord
7
+ autoload :Missing, 'i18n/backend/active_record/missing'
8
+ autoload :StoreProcs, 'i18n/backend/active_record/store_procs'
9
+ autoload :Translation, 'i18n/backend/active_record/translation'
10
+
11
+ module Implementation
12
+ include Base, Flatten
13
+
14
+ def available_locales
15
+ begin
16
+ Translation.available_locales
17
+ rescue ::ActiveRecord::StatementInvalid
18
+ []
19
+ end
20
+ end
21
+
22
+ def store_translations(locale, data, options = {})
23
+ escape = options.fetch(:escape, true)
24
+ flatten_translations(locale, data, escape, false).each do |key, value|
25
+ Translation.locale(locale).lookup(expand_keys(key)).delete_all
26
+ Translation.create(:locale => locale.to_s, :key => key.to_s, :value => value)
27
+ end
28
+ end
29
+
30
+ protected
31
+
32
+ def lookup(locale, key, scope = [], options = {})
33
+ key = normalize_flat_keys(locale, key, scope, options[:separator])
34
+ result = Translation.locale(locale).lookup(key).all
35
+
36
+ if result.empty?
37
+ nil
38
+ elsif result.first.key == key
39
+ result.first.value
40
+ else
41
+ chop_range = (key.size + FLATTEN_SEPARATOR.size)..-1
42
+ result = result.inject({}) do |hash, r|
43
+ hash[r.key.slice(chop_range)] = r.value
44
+ hash
45
+ end
46
+ result.deep_symbolize_keys
47
+ end
48
+ end
49
+
50
+ # For a key :'foo.bar.baz' return ['foo', 'foo.bar', 'foo.bar.baz']
51
+ def expand_keys(key)
52
+ key.to_s.split(FLATTEN_SEPARATOR).inject([]) do |keys, key|
53
+ keys << [keys.last, key].compact.join(FLATTEN_SEPARATOR)
54
+ end
55
+ end
56
+ end
57
+
58
+ include Implementation
59
+ end
60
+ end
61
+ end
62
+
@@ -0,0 +1,66 @@
1
+ # This extension stores translation stub records for missing translations to
2
+ # the database.
3
+ #
4
+ # This is useful if you have a web based translation tool. It will populate
5
+ # the database with untranslated keys as the application is being used. A
6
+ # translator can then go through these and add missing translations.
7
+ #
8
+ # Example usage:
9
+ #
10
+ # I18n::Backend::Chain.send(:include, I18n::Backend::ActiveRecord::Missing)
11
+ # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::ActiveRecord.new, I18n::Backend::Simple.new)
12
+ #
13
+ # Stub records for pluralizations will also be created for each key defined
14
+ # in i18n.plural.keys.
15
+ #
16
+ # For example:
17
+ #
18
+ # # en.yml
19
+ # en:
20
+ # i18n:
21
+ # plural:
22
+ # keys: [:zero, :one, :other]
23
+ #
24
+ # # pl.yml
25
+ # pl:
26
+ # i18n:
27
+ # plural:
28
+ # keys: [:zero, :one, :few, :other]
29
+ #
30
+ # It will also persist interpolation keys in Translation#interpolations so
31
+ # translators will be able to review and use them.
32
+ module I18n
33
+ module Backend
34
+ class ActiveRecord
35
+ module Missing
36
+ include Flatten
37
+
38
+ def store_default_translations(locale, key, options = {})
39
+ count, scope, default, separator = options.values_at(:count, :scope, :default, :separator)
40
+ separator ||= I18n.default_separator
41
+ key = normalize_flat_keys(locale, key, scope, separator)
42
+
43
+ unless ActiveRecord::Translation.locale(locale).lookup(key).exists?
44
+ interpolations = options.keys - I18n::RESERVED_KEYS
45
+ keys = count ? I18n.t('i18n.plural.keys', :locale => locale).map { |k| [key, k].join(FLATTEN_SEPARATOR) } : [key]
46
+ keys.each { |key| store_default_translation(locale, key, interpolations) }
47
+ end
48
+ end
49
+
50
+ def store_default_translation(locale, key, interpolations)
51
+ translation = ActiveRecord::Translation.new :locale => locale.to_s, :key => key
52
+ translation.interpolations = interpolations
53
+ translation.save
54
+ end
55
+
56
+ def translate(locale, key, options = {})
57
+ super
58
+ rescue I18n::MissingTranslationData => e
59
+ self.store_default_translations(locale, key, options)
60
+ raise e
61
+ end
62
+ end
63
+ end
64
+ end
65
+ end
66
+
@@ -0,0 +1,39 @@
1
+ # This module is intended to be mixed into the ActiveRecord backend to allow
2
+ # storing Ruby Procs as translation values in the database.
3
+ #
4
+ # I18n.backend = I18n::Backend::ActiveRecord.new
5
+ # I18n::Backend::ActiveRecord::Translation.send(:include, I18n::Backend::ActiveRecord::StoreProcs)
6
+ #
7
+ # The StoreProcs module requires the ParseTree and ruby2ruby gems and therefor
8
+ # was extracted from the original backend.
9
+ #
10
+ # ParseTree is not compatible with Ruby 1.9.
11
+
12
+ begin
13
+ require 'ruby2ruby'
14
+ require 'parse_tree'
15
+ require 'parse_tree_extensions'
16
+ rescue LoadError => e
17
+ puts "can't use StoreProcs because: #{e.message}"
18
+ end
19
+
20
+ module I18n
21
+ module Backend
22
+ class ActiveRecord
23
+ module StoreProcs
24
+ def value=(v)
25
+ case v
26
+ when Proc
27
+ write_attribute(:value, v.to_ruby)
28
+ write_attribute(:is_proc, true)
29
+ else
30
+ write_attribute(:value, v)
31
+ end
32
+ end
33
+
34
+ Translation.send(:include, self) if method(:to_s).respond_to?(:to_ruby)
35
+ end
36
+ end
37
+ end
38
+ end
39
+
@@ -0,0 +1,111 @@
1
+ require 'active_record'
2
+
3
+ module I18n
4
+ module Backend
5
+ # ActiveRecord model used to store actual translations to the database.
6
+ #
7
+ # This model expects a table like the following to be already set up in
8
+ # your the database:
9
+ #
10
+ # create_table :translations do |t|
11
+ # t.string :locale
12
+ # t.string :key
13
+ # t.text :value
14
+ # t.text :interpolations
15
+ # t.boolean :is_proc, :default => false
16
+ # end
17
+ #
18
+ # This model supports to named scopes :locale and :lookup. The :locale
19
+ # scope simply adds a condition for a given locale:
20
+ #
21
+ # I18n::Backend::ActiveRecord::Translation.locale(:en).all
22
+ # # => all translation records that belong to the :en locale
23
+ #
24
+ # The :lookup scope adds a condition for looking up all translations
25
+ # that either start with the given keys (joined by an optionally given
26
+ # separator or I18n.default_separator) or that exactly have this key.
27
+ #
28
+ # # with translations present for :"foo.bar" and :"foo.baz"
29
+ # I18n::Backend::ActiveRecord::Translation.lookup(:foo)
30
+ # # => an array with both translation records :"foo.bar" and :"foo.baz"
31
+ #
32
+ # I18n::Backend::ActiveRecord::Translation.lookup([:foo, :bar])
33
+ # I18n::Backend::ActiveRecord::Translation.lookup(:"foo.bar")
34
+ # # => an array with the translation record :"foo.bar"
35
+ #
36
+ # When the StoreProcs module was mixed into this model then Procs will
37
+ # be stored to the database as Ruby code and evaluated when :value is
38
+ # called.
39
+ #
40
+ # Translation = I18n::Backend::ActiveRecord::Translation
41
+ # Translation.create \
42
+ # :locale => 'en'
43
+ # :key => 'foo'
44
+ # :value => lambda { |key, options| 'FOO' }
45
+ # Translation.find_by_locale_and_key('en', 'foo').value
46
+ # # => 'FOO'
47
+ class ActiveRecord
48
+ class Translation < ::ActiveRecord::Base
49
+ TRUTHY_CHAR = "\001"
50
+ FALSY_CHAR = "\002"
51
+
52
+ self.table_name = 'translations'
53
+ attr_protected :is_proc, :interpolations
54
+
55
+ serialize :value
56
+ serialize :interpolations, Array
57
+
58
+ class << self
59
+ def locale(locale)
60
+ scoped(:conditions => { :locale => locale.to_s })
61
+ end
62
+
63
+ def lookup(keys, *separator)
64
+ column_name = connection.quote_column_name('key')
65
+ keys = Array(keys).map! { |key| key.to_s }
66
+
67
+ unless separator.empty?
68
+ warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " <<
69
+ "You can change the internal separator by overwriting FLATTEN_SEPARATOR."
70
+ end
71
+
72
+ namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%"
73
+ scoped(:conditions => ["#{column_name} IN (?) OR #{column_name} LIKE ?", keys, namespace])
74
+ end
75
+
76
+ def available_locales
77
+ Translation.find(:all, :select => 'DISTINCT locale').map { |t| t.locale.to_sym }
78
+ end
79
+ end
80
+
81
+ def interpolates?(key)
82
+ self.interpolations.include?(key) if self.interpolations
83
+ end
84
+
85
+ def value
86
+ value = read_attribute(:value)
87
+ if is_proc
88
+ Kernel.eval(value)
89
+ elsif value == FALSY_CHAR
90
+ false
91
+ elsif value == TRUTHY_CHAR
92
+ true
93
+ else
94
+ value
95
+ end
96
+ end
97
+
98
+ def value=(value)
99
+ if value === false
100
+ value = FALSY_CHAR
101
+ elsif value === true
102
+ value = TRUTHY_CHAR
103
+ end
104
+
105
+ write_attribute(:value, value)
106
+ end
107
+ end
108
+ end
109
+ end
110
+ end
111
+
@@ -0,0 +1,54 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class I18nBackendActiveRecordTest < Test::Unit::TestCase
4
+ def setup
5
+ I18n.backend = I18n::Backend::ActiveRecord.new
6
+ store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
7
+ end
8
+
9
+ def teardown
10
+ I18n::Backend::ActiveRecord::Translation.destroy_all
11
+ super
12
+ end
13
+
14
+ test "store_translations does not allow ambiguous keys (1)" do
15
+ I18n::Backend::ActiveRecord::Translation.delete_all
16
+ I18n.backend.store_translations(:en, :foo => 'foo')
17
+ I18n.backend.store_translations(:en, :foo => { :bar => 'bar' })
18
+ I18n.backend.store_translations(:en, :foo => { :baz => 'baz' })
19
+
20
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').all
21
+ assert_equal %w(bar baz), translations.map(&:value)
22
+
23
+ assert_equal({ :bar => 'bar', :baz => 'baz' }, I18n.t(:foo))
24
+ end
25
+
26
+ test "store_translations does not allow ambiguous keys (2)" do
27
+ I18n::Backend::ActiveRecord::Translation.delete_all
28
+ I18n.backend.store_translations(:en, :foo => { :bar => 'bar' })
29
+ I18n.backend.store_translations(:en, :foo => { :baz => 'baz' })
30
+ I18n.backend.store_translations(:en, :foo => 'foo')
31
+
32
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo').all
33
+ assert_equal %w(foo), translations.map(&:value)
34
+
35
+ assert_equal 'foo', I18n.t(:foo)
36
+ end
37
+
38
+ test "can store translations with keys that are translations containing special chars" do
39
+ I18n.backend.store_translations(:es, :"Pagina's" => "Pagina's" )
40
+ assert_equal "Pagina's", I18n.t(:"Pagina's", :locale => :es)
41
+ end
42
+
43
+ with_mocha do
44
+ test "missing translations table does not cause an error in #available_locales" do
45
+ I18n::Backend::ActiveRecord::Translation.expects(:available_locales).raises(::ActiveRecord::StatementInvalid)
46
+ assert_equal [], I18n.backend.available_locales
47
+ end
48
+ end
49
+
50
+ def test_expand_keys
51
+ assert_equal %w(foo foo.bar foo.bar.baz), I18n.backend.send(:expand_keys, :'foo.bar.baz')
52
+ end
53
+ end if defined?(ActiveRecord)
54
+
@@ -0,0 +1,7 @@
1
+ dir = File.dirname(__FILE__)
2
+ $:.unshift(dir)
3
+
4
+ Dir["#{dir}/**/*_test.rb"].sort.each do |file|
5
+ require file.sub(/^#{dir}\/(.*)\.rb$/, '\1')
6
+ end
7
+
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class I18nActiveRecordApiTest < Test::Unit::TestCase
4
+ def setup
5
+ I18n.backend = I18n::Backend::ActiveRecord.new
6
+ super
7
+ end
8
+
9
+ def self.can_store_procs?
10
+ I18n::Backend::ActiveRecord.included_modules.include?(I18n::Backend::ActiveRecord::StoreProcs)
11
+ end
12
+
13
+ include I18n::Tests::Basics
14
+ include I18n::Tests::Defaults
15
+ include I18n::Tests::Interpolation
16
+ include I18n::Tests::Link
17
+ include I18n::Tests::Lookup
18
+ include I18n::Tests::Pluralization
19
+ include I18n::Tests::Procs if can_store_procs?
20
+
21
+ include I18n::Tests::Localization::Date
22
+ include I18n::Tests::Localization::DateTime
23
+ include I18n::Tests::Localization::Time
24
+ include I18n::Tests::Localization::Procs if can_store_procs?
25
+
26
+ test "make sure we use an ActiveRecord backend" do
27
+ assert_equal I18n::Backend::ActiveRecord, I18n.backend.class
28
+ end
29
+ end if defined?(ActiveRecord)
30
+
@@ -0,0 +1,71 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class I18nActiveRecordMissingTest < Test::Unit::TestCase
4
+ class Backend < I18n::Backend::ActiveRecord
5
+ include I18n::Backend::ActiveRecord::Missing
6
+ end
7
+
8
+ def setup
9
+ I18n.backend.store_translations(:en, :bar => 'Bar', :i18n => { :plural => { :keys => [:zero, :one, :other] } })
10
+ I18n.backend = I18n::Backend::Chain.new(Backend.new, I18n.backend)
11
+ I18n::Backend::ActiveRecord::Translation.delete_all
12
+ end
13
+
14
+ test "can persist interpolations" do
15
+ translation = I18n::Backend::ActiveRecord::Translation.new(:key => 'foo', :value => 'bar', :locale => :en)
16
+ translation.interpolations = %w(count name)
17
+ translation.save
18
+ assert translation.valid?
19
+ end
20
+
21
+ test "lookup persists the key" do
22
+ I18n.t('foo.bar.baz')
23
+ assert_equal 1, I18n::Backend::ActiveRecord::Translation.count
24
+ assert I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo.bar.baz')
25
+ end
26
+
27
+ test "lookup does not persist the key twice" do
28
+ 2.times { I18n.t('foo.bar.baz') }
29
+ assert_equal 1, I18n::Backend::ActiveRecord::Translation.count
30
+ assert I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key('foo.bar.baz')
31
+ end
32
+
33
+ test "lookup persists interpolation keys when looked up directly" do
34
+ I18n.t('foo.bar.baz', :cow => "lucy" ) # creates stub translation.
35
+ translation_stub = I18n::Backend::ActiveRecord::Translation.locale(:en).lookup('foo.bar.baz').first
36
+ assert translation_stub.interpolates?(:cow)
37
+ end
38
+
39
+ test "creates one stub per pluralization" do
40
+ I18n.t('foo', :count => 999)
41
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).find_all_by_key %w{ foo.zero foo.one foo.other }
42
+ assert_equal 3, translations.length
43
+ end
44
+
45
+ test "creates no stub for base key in pluralization" do
46
+ I18n.t('foo', :count => 999)
47
+ assert_equal 3, I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo").count
48
+ assert !I18n::Backend::ActiveRecord::Translation.locale(:en).find_by_key("foo")
49
+ end
50
+
51
+ test "creates a stub when a custom separator is used" do
52
+ I18n.t('foo|baz', :separator => '|')
53
+ I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo.baz").first.update_attributes!(:value => 'baz!')
54
+ assert_equal 'baz!', I18n.t('foo|baz', :separator => '|')
55
+ end
56
+
57
+ test "creates a stub per pluralization when a custom separator is used" do
58
+ I18n.t('foo|bar', :count => 999, :separator => '|')
59
+ translations = I18n::Backend::ActiveRecord::Translation.locale(:en).find_all_by_key %w{ foo.bar.zero foo.bar.one foo.bar.other }
60
+ assert_equal 3, translations.length
61
+ end
62
+
63
+ test "creates a stub when a custom separator is used and the key contains the flatten separator (a dot character)" do
64
+ key = 'foo|baz.zab'
65
+ I18n.t(key, :separator => '|')
66
+ I18n::Backend::ActiveRecord::Translation.locale(:en).lookup("foo.baz\001zab").first.update_attributes!(:value => 'baz!')
67
+ assert_equal 'baz!', I18n.t(key, :separator => '|')
68
+ end
69
+
70
+ end if defined?(ActiveRecord)
71
+
@@ -0,0 +1,56 @@
1
+ require 'test_setup'
2
+
3
+ I18n::Tests.parse_options!
4
+ require 'bundler/setup'
5
+ $:.unshift File.expand_path("../lib", File.dirname(__FILE__))
6
+ require 'i18n/active_record'
7
+ require 'i18n/tests'
8
+ require 'mocha'
9
+ I18n::Tests.setup_active_record
10
+
11
+ class Test::Unit::TestCase
12
+ def self.test(name, &block)
13
+ test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
14
+ defined = instance_method(test_name) rescue false
15
+ raise "#{test_name} is already defined in #{self}" if defined
16
+ if block_given?
17
+ define_method(test_name, &block)
18
+ else
19
+ define_method(test_name) do
20
+ flunk "No implementation provided for #{name}"
21
+ end
22
+ end
23
+ end
24
+
25
+ def self.with_mocha
26
+ yield if Object.respond_to?(:expects)
27
+ end
28
+
29
+ def teardown
30
+ I18n.locale = nil
31
+ I18n.default_locale = :en
32
+ I18n.load_path = []
33
+ I18n.available_locales = nil
34
+ I18n.backend = nil
35
+ end
36
+
37
+ def translations
38
+ I18n.backend.instance_variable_get(:@translations)
39
+ end
40
+
41
+ def store_translations(*args)
42
+ data = args.pop
43
+ locale = args.pop || :en
44
+ I18n.backend.store_translations(locale, data)
45
+ end
46
+
47
+ def locales_dir
48
+ File.dirname(__FILE__) + '/test_data/locales'
49
+ end
50
+ end
51
+
52
+ Object.class_eval do
53
+ def meta_class
54
+ class << self; self; end
55
+ end
56
+ end unless Object.method_defined?(:meta_class)
@@ -0,0 +1,92 @@
1
+ $KCODE = 'u' if RUBY_VERSION <= '1.9'
2
+
3
+ require 'rubygems'
4
+ require 'test/unit'
5
+ require 'optparse'
6
+
7
+ # Do not load the i18n gem from libraries like active_support.
8
+ #
9
+ # This is required for testing against Rails 2.3 because active_support/vendor.rb#24 tries
10
+ # to load I18n using the gem method. Instead, we want to test the local library of course.
11
+ alias :gem_for_ruby_19 :gem # for 1.9. gives a super ugly seg fault otherwise
12
+ def gem(gem_name, *version_requirements)
13
+ puts("skipping loading the i18n gem ...") && return if gem_name =='i18n'
14
+ super(gem_name, *version_requirements)
15
+ end
16
+
17
+ module I18n
18
+ module Tests
19
+ class << self
20
+ def options
21
+ @options ||= { :with => [], :adapter => 'sqlite3' }
22
+ end
23
+
24
+ def parse_options!
25
+ OptionParser.new do |o|
26
+ o.on('-w', '--with DEPENDENCIES', 'Define dependencies') do |dep|
27
+ options[:with] = dep.split(',').map { |group| group.to_sym }
28
+ end
29
+ end.parse!
30
+
31
+ options[:with].each do |dep|
32
+ case dep
33
+ when :sqlite3, :mysql, :postgres
34
+ @options[:adapter] = dep
35
+ when :r23, :'rails-2.3.x'
36
+ ENV['BUNDLE_GEMFILE'] = 'ci/Gemfile.rails-2.3.x'
37
+ when :r3, :'rails-3.0.x'
38
+ ENV['BUNDLE_GEMFILE'] = 'ci/Gemfile.rails-3.x'
39
+ when :'no-rails'
40
+ ENV['BUNDLE_GEMFILE'] = 'ci/Gemfile.no-rails'
41
+ end
42
+ end
43
+
44
+ ENV['BUNDLE_GEMFILE'] ||= 'ci/Gemfile.all'
45
+ end
46
+
47
+ def setup_active_record
48
+ begin
49
+ require 'active_record'
50
+ ActiveRecord::Base.connection
51
+ true
52
+ rescue LoadError => e
53
+ puts "can't use ActiveRecord backend because: #{e.message}"
54
+ rescue ActiveRecord::ConnectionNotEstablished
55
+ require 'i18n/backend/active_record'
56
+ require 'i18n/backend/active_record/store_procs'
57
+ connect_active_record
58
+ true
59
+ end
60
+ end
61
+
62
+ def connect_active_record
63
+ connect_adapter
64
+ ActiveRecord::Migration.verbose = false
65
+ ActiveRecord::Schema.define(:version => 1) do
66
+ create_table :translations, :force => true do |t|
67
+ t.string :locale
68
+ t.string :key
69
+ t.text :value
70
+ t.text :interpolations
71
+ t.boolean :is_proc, :default => false
72
+ end
73
+ add_index :translations, [:locale, :key], :unique => true
74
+ end
75
+ end
76
+
77
+ def connect_adapter
78
+ case options[:adapter].to_sym
79
+ when :sqlite3
80
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
81
+ when :mysql
82
+ # CREATE DATABASE i18n_unittest;
83
+ # CREATE USER 'i18n'@'localhost' IDENTIFIED BY '';
84
+ # GRANT ALL PRIVILEGES ON i18n_unittest.* to 'i18n'@'localhost';
85
+ ActiveRecord::Base.establish_connection(:adapter => "mysql", :database => "i18n_unittest", :username => "i18n", :password => "", :host => "localhost")
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+
metadata ADDED
@@ -0,0 +1,81 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: arena-i18n-active_record
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.4
6
+ platform: ruby
7
+ authors:
8
+ - Sven Fuchs
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-07-11 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: i18n
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.5.0
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ description: I18n ActiveRecord backend. Allows to store translations in a database using ActiveRecord, e.g. for providing a web-interface for managing translations.
27
+ email: svenfuchs@artweb-design.de
28
+ executables: []
29
+
30
+ extensions: []
31
+
32
+ extra_rdoc_files: []
33
+
34
+ files:
35
+ - ci/Gemfile.rails-3.x
36
+ - ci/Gemfile.rails-3.x.lock
37
+ - lib/i18n/active_record/version.rb
38
+ - lib/i18n/active_record.rb
39
+ - lib/i18n/backend/active_record/missing.rb
40
+ - lib/i18n/backend/active_record/store_procs.rb
41
+ - lib/i18n/backend/active_record/translation.rb
42
+ - lib/i18n/backend/active_record.rb
43
+ - test/active_record_test.rb
44
+ - test/all.rb
45
+ - test/api_test.rb
46
+ - test/missing_test.rb
47
+ - test/test_helper.rb
48
+ - test/test_setup.rb
49
+ - MIT-LICENSE
50
+ - README.textile
51
+ - Rakefile
52
+ homepage: http://github.com/arenaflowers/i18n-active_record
53
+ licenses: []
54
+
55
+ post_install_message:
56
+ rdoc_options: []
57
+
58
+ require_paths:
59
+ - lib
60
+ required_ruby_version: !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ version: "0"
72
+ requirements: []
73
+
74
+ rubyforge_project: "[none]"
75
+ rubygems_version: 1.8.24
76
+ signing_key:
77
+ specification_version: 3
78
+ summary: I18n ActiveRecord backend
79
+ test_files: []
80
+
81
+ has_rdoc: