i18n-inline_forms 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "http://rubygems.org"
2
+
3
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,91 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ i18n-inline_forms (0.1)
5
+ i18n (>= 0.5.0)
6
+
7
+ GEM
8
+ remote: http://rubygems.org/
9
+ specs:
10
+ actionpack (3.2.2)
11
+ activemodel (= 3.2.2)
12
+ activesupport (= 3.2.2)
13
+ builder (~> 3.0.0)
14
+ erubis (~> 2.7.0)
15
+ journey (~> 1.0.1)
16
+ rack (~> 1.4.0)
17
+ rack-cache (~> 1.1)
18
+ rack-test (~> 0.6.1)
19
+ sprockets (~> 2.1.2)
20
+ activemodel (3.2.2)
21
+ activesupport (= 3.2.2)
22
+ builder (~> 3.0.0)
23
+ activesupport (3.2.2)
24
+ i18n (~> 0.6)
25
+ multi_json (~> 1.0)
26
+ builder (3.0.0)
27
+ diff-lcs (1.1.3)
28
+ erubis (2.7.0)
29
+ git (1.2.5)
30
+ hike (1.2.1)
31
+ i18n (0.6.0)
32
+ jeweler (1.5.2)
33
+ bundler (~> 1.0.0)
34
+ git (>= 1.2.5)
35
+ rake
36
+ journey (1.0.3)
37
+ json (1.6.5)
38
+ multi_json (1.1.0)
39
+ rack (1.4.1)
40
+ rack-cache (1.2)
41
+ rack (>= 0.4)
42
+ rack-ssl (1.3.2)
43
+ rack
44
+ rack-test (0.6.1)
45
+ rack (>= 1.0)
46
+ railties (3.2.2)
47
+ actionpack (= 3.2.2)
48
+ activesupport (= 3.2.2)
49
+ rack-ssl (~> 1.3.2)
50
+ rake (>= 0.8.7)
51
+ rdoc (~> 3.4)
52
+ thor (~> 0.14.6)
53
+ rake (0.9.2.2)
54
+ rcov (1.0.0)
55
+ rdoc (3.12)
56
+ json (~> 1.4)
57
+ rspec (2.8.0)
58
+ rspec-core (~> 2.8.0)
59
+ rspec-expectations (~> 2.8.0)
60
+ rspec-mocks (~> 2.8.0)
61
+ rspec-core (2.8.0)
62
+ rspec-expectations (2.8.0)
63
+ diff-lcs (~> 1.1.2)
64
+ rspec-mocks (2.8.0)
65
+ rspec-rails (2.8.1)
66
+ actionpack (>= 3.0)
67
+ activesupport (>= 3.0)
68
+ railties (>= 3.0)
69
+ rspec (~> 2.8.0)
70
+ shoulda (3.0.1)
71
+ shoulda-context (~> 1.0.0)
72
+ shoulda-matchers (~> 1.0.0)
73
+ shoulda-context (1.0.0)
74
+ shoulda-matchers (1.0.0)
75
+ sprockets (2.1.2)
76
+ hike (~> 1.2)
77
+ rack (~> 1.0)
78
+ tilt (~> 1.1, != 1.3.0)
79
+ thor (0.14.6)
80
+ tilt (1.3.3)
81
+
82
+ PLATFORMS
83
+ ruby
84
+
85
+ DEPENDENCIES
86
+ bundler (~> 1.0.0)
87
+ i18n-inline_forms!
88
+ jeweler (~> 1.5.2)
89
+ rcov
90
+ rspec-rails
91
+ shoulda
data/MIT-LICENSE ADDED
@@ -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
+
data/README ADDED
File without changes
data/README.textile ADDED
@@ -0,0 +1,70 @@
1
+ h1. I18n::Backend::InlineForms
2
+
3
+ This repository contains the I18n InlineForms 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-inline_forms'
11
+ </pre>
12
+
13
+ Next create a active record model named @Translation@ with the Rails Generator.
14
+ Your migration should look like this:
15
+
16
+ <pre>
17
+ class CreateTranslations < InlineForms::Migration
18
+ def self.up
19
+ create_table :translations do |t|
20
+ t.string :locale
21
+ t.string :key
22
+ t.text :value
23
+ t.text :interpolations
24
+ t.boolean :is_proc, :default => false
25
+
26
+ t.timestamps
27
+ end
28
+ end
29
+
30
+ def self.down
31
+ drop_table :translations
32
+ end
33
+ end
34
+ </pre>
35
+
36
+ With this translation model you will be able to manage your translation, and add new translations or languages through
37
+ it.
38
+
39
+ To load @I18n::Backend::InlineForms@ into your Rails application, create a new file in *config/initializers* named *locale.rb*.
40
+
41
+ A simple configuration for your locale.rb could look like this:
42
+
43
+ <pre>
44
+ require 'i18n/backend/inline_forms'
45
+ I18n.backend = I18n::Backend::InlineForms.new
46
+ </pre>
47
+
48
+ A more adavanced example (Thanks Moritz), which uses YAML files and InlineForms for lookups:
49
+
50
+ <pre>
51
+ require 'i18n/backend/inline_forms'
52
+ I18n.backend = I18n::Backend::InlineForms.new
53
+
54
+ I18n::Backend::InlineForms.send(:include, I18n::Backend::Memoize)
55
+ I18n::Backend::InlineForms.send(:include, I18n::Backend::Flatten)
56
+ I18n::Backend::Simple.send(:include, I18n::Backend::Memoize)
57
+ I18n::Backend::Simple.send(:include, I18n::Backend::Pluralization)
58
+
59
+ I18n.backend = I18n::Backend::Chain.new(I18n::Backend::Simple.new, I18n.backend)
60
+ </pre>
61
+
62
+ h2. Usage
63
+
64
+ You can now use @I18n.t('Your String')@ to lookup translations in the database.
65
+
66
+ h2. Maintainers
67
+
68
+ * Sven Fuchs
69
+
70
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ $:.unshift File.expand_path('../lib', __FILE__)
4
+ require 'i18n/inline_forms/version'
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "i18n-inline_forms"
8
+ s.version = I18n::InlineForms::VERSION
9
+ s.authors = ["Ace Suares"]
10
+ s.email = "ace@suares.com"
11
+ s.homepage = "http://github.com/acesuares/i18n-inline_forms"
12
+ s.summary = "I18n InlineForms backend"
13
+ s.description = "I18n InlineForms backend. Allows to store translations in a database using InlineForms, e.g. for providing a web-interface for managing translations. Forked from i18n-active_record by Sven Fuchs."
14
+
15
+ s.platform = Gem::Platform::RUBY
16
+
17
+ s.add_dependency 'i18n', '>= 0.5.0'
18
+
19
+ s.rubyforge_project = "i18n-inline_forms"
20
+
21
+ s.files = `git ls-files`.split("\n")
22
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
23
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
24
+ s.require_paths = ["lib"]
25
+
26
+ s.add_development_dependency(%q<rspec-rails>, [">= 0"])
27
+ s.add_development_dependency(%q<shoulda>, [">= 0"])
28
+ s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
29
+ s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
30
+ s.add_development_dependency(%q<rcov>, [">= 0"])
31
+
32
+ end
33
+
@@ -0,0 +1,62 @@
1
+ require 'i18n/backend/base'
2
+ require 'i18n/backend/inline_forms/translation'
3
+
4
+ module I18n
5
+ module Backend
6
+ class InlineForms
7
+ autoload :Missing, 'i18n/backend/inline_forms/missing'
8
+ autoload :StoreProcs, 'i18n/backend/inline_forms/store_procs'
9
+ autoload :Translation, 'i18n/backend/inline_forms/translation'
10
+
11
+ module Implementation
12
+ include Base, Flatten
13
+
14
+ def available_locales
15
+ begin
16
+ Translation.available_locales
17
+ rescue ::InlineForms::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::InlineForms::Missing)
11
+ # I18n.backend = I18n::Backend::Chain.new(I18n::Backend::InlineForms.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 InlineForms
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 InlineForms::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 = InlineForms::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 InlineForms backend to allow
2
+ # storing Ruby Procs as translation values in the database.
3
+ #
4
+ # I18n.backend = I18n::Backend::InlineForms.new
5
+ # I18n::Backend::InlineForms::Translation.send(:include, I18n::Backend::InlineForms::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 InlineForms
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,132 @@
1
+ require 'inline_forms'
2
+
3
+ module I18n
4
+ module Backend
5
+ # InlineForms 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
+
19
+
20
+ # 2012-03-10 'key' is a reserved keyword in MySQL 5 so we create the table
21
+ # like this:
22
+ #
23
+ # create_table :translations do |t|
24
+ # t.string :locale
25
+ # t.string :thekey
26
+ # t.text :value
27
+ # t.text :interpolations
28
+ # t.boolean :is_proc, :default => false
29
+ # end
30
+ #
31
+ # and in our model we alias key alias_attribute :key, :thekey
32
+ #
33
+ #also rails 3 scoping
34
+ #
35
+
36
+
37
+ #
38
+ # This model supports to named scopes :locale and :lookup. The :locale
39
+ # scope simply adds a condition for a given locale:
40
+ #
41
+ # I18n::Backend::InlineForms::Translation.locale(:en).all
42
+ # # => all translation records that belong to the :en locale
43
+ #
44
+ # The :lookup scope adds a condition for looking up all translations
45
+ # that either start with the given keys (joined by an optionally given
46
+ # separator or I18n.default_separator) or that exactly have this key.
47
+ #
48
+ # # with translations present for :"foo.bar" and :"foo.baz"
49
+ # I18n::Backend::InlineForms::Translation.lookup(:foo)
50
+ # # => an array with both translation records :"foo.bar" and :"foo.baz"
51
+ #
52
+ # I18n::Backend::InlineForms::Translation.lookup([:foo, :bar])
53
+ # I18n::Backend::InlineForms::Translation.lookup(:"foo.bar")
54
+ # # => an array with the translation record :"foo.bar"
55
+ #
56
+ # When the StoreProcs module was mixed into this model then Procs will
57
+ # be stored to the database as Ruby code and evaluated when :value is
58
+ # called.
59
+ #
60
+ # Translation = I18n::Backend::InlineForms::Translation
61
+ # Translation.create \
62
+ # :locale => 'en'
63
+ # :key => 'foo'
64
+ # :value => lambda { |key, options| 'FOO' }
65
+ # Translation.find_by_locale_and_key('en', 'foo').value
66
+ # # => 'FOO'
67
+ class InlineForms
68
+ class Translation < ::InlineForms::Base
69
+ TRUTHY_CHAR = "\001"
70
+ FALSY_CHAR = "\002"
71
+
72
+ set_table_name 'translations'
73
+ attr_protected :is_proc, :interpolations
74
+
75
+ serialize :value
76
+ serialize :interpolations, Array
77
+
78
+ alias_attribute :key, :thekey
79
+
80
+ scope :locale, lambda { |locale|
81
+ where('locale = ? ', locale.to_s)
82
+ }
83
+
84
+ scope :lookup, lambda { |keys, *separator|
85
+ keys = Array(keys).map! { |key| key.to_s }
86
+
87
+ unless separator.empty?
88
+ warn "[DEPRECATION] Giving a separator to Translation.lookup is deprecated. " <<
89
+ "You can change the internal separator by overwriting FLATTEN_SEPARATOR."
90
+ end
91
+
92
+ namespace = "#{keys.last}#{I18n::Backend::Flatten::FLATTEN_SEPARATOR}%"
93
+ where("thekey IN (?) OR thekey LIKE ?", keys, namespace)
94
+ }
95
+
96
+ class << self
97
+ def available_locales
98
+ Translation.select(:locale).uniq.map { |t| t.locale.to_sym }
99
+ end
100
+ end
101
+
102
+ def interpolates?(key)
103
+ self.interpolations.include?(key) if self.interpolations
104
+ end
105
+
106
+ def value
107
+ value = read_attribute(:value)
108
+ if is_proc
109
+ Kernel.eval(value)
110
+ elsif value == FALSY_CHAR
111
+ false
112
+ elsif value == TRUTHY_CHAR
113
+ true
114
+ else
115
+ value
116
+ end
117
+ end
118
+
119
+ def value=(value)
120
+ if value === false
121
+ value = FALSY_CHAR
122
+ elsif value === true
123
+ value = TRUTHY_CHAR
124
+ end
125
+
126
+ write_attribute(:value, value)
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
132
+
@@ -0,0 +1 @@
1
+ require 'i18n'
@@ -0,0 +1,6 @@
1
+ module I18n
2
+ module InlineForms
3
+ VERSION = "0.1"
4
+ end
5
+ end
6
+
data/test/all.rb ADDED
@@ -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
+
data/test/api_test.rb ADDED
@@ -0,0 +1,30 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class I18nInlineFormsApiTest < Test::Unit::TestCase
4
+ def setup
5
+ I18n.backend = I18n::Backend::InlineForms.new
6
+ super
7
+ end
8
+
9
+ def self.can_store_procs?
10
+ I18n::Backend::InlineForms.included_modules.include?(I18n::Backend::InlineForms::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 InlineForms backend" do
27
+ assert_equal I18n::Backend::InlineForms, I18n.backend.class
28
+ end
29
+ end if defined?(InlineForms)
30
+
@@ -0,0 +1,54 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class I18nBackendInlineFormsTest < Test::Unit::TestCase
4
+ def setup
5
+ I18n.backend = I18n::Backend::InlineForms.new
6
+ store_translations(:en, :foo => { :bar => 'bar', :baz => 'baz' })
7
+ end
8
+
9
+ def teardown
10
+ I18n::Backend::InlineForms::Translation.destroy_all
11
+ super
12
+ end
13
+
14
+ test "store_translations does not allow ambiguous keys (1)" do
15
+ I18n::Backend::InlineForms::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::InlineForms::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::InlineForms::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::InlineForms::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::InlineForms::Translation.expects(:available_locales).raises(::InlineForms::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?(InlineForms)
54
+
@@ -0,0 +1,71 @@
1
+ require File.expand_path('../test_helper', __FILE__)
2
+
3
+ class I18nInlineFormsMissingTest < Test::Unit::TestCase
4
+ class Backend < I18n::Backend::InlineForms
5
+ include I18n::Backend::InlineForms::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::InlineForms::Translation.delete_all
12
+ end
13
+
14
+ test "can persist interpolations" do
15
+ translation = I18n::Backend::InlineForms::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::InlineForms::Translation.count
24
+ assert I18n::Backend::InlineForms::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::InlineForms::Translation.count
30
+ assert I18n::Backend::InlineForms::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::InlineForms::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::InlineForms::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::InlineForms::Translation.locale(:en).lookup("foo").count
48
+ assert !I18n::Backend::InlineForms::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::InlineForms::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::InlineForms::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::InlineForms::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?(InlineForms)
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/inline_forms'
7
+ require 'i18n/tests'
8
+ require 'mocha'
9
+ I18n::Tests.setup_inline_forms
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_inline_forms
48
+ begin
49
+ require 'inline_forms'
50
+ InlineForms::Base.connection
51
+ true
52
+ rescue LoadError => e
53
+ puts "can't use InlineForms backend because: #{e.message}"
54
+ rescue InlineForms::ConnectionNotEstablished
55
+ require 'i18n/backend/inline_forms'
56
+ require 'i18n/backend/inline_forms/store_procs'
57
+ connect_inline_forms
58
+ true
59
+ end
60
+ end
61
+
62
+ def connect_inline_forms
63
+ connect_adapter
64
+ InlineForms::Migration.verbose = false
65
+ InlineForms::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
+ InlineForms::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
+ InlineForms::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,171 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: i18n-inline_forms
3
+ version: !ruby/object:Gem::Version
4
+ hash: 9
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ version: "0.1"
10
+ platform: ruby
11
+ authors:
12
+ - Ace Suares
13
+ autorequire:
14
+ bindir: bin
15
+ cert_chain: []
16
+
17
+ date: 2012-03-10 00:00:00 Z
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: i18n
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ">="
26
+ - !ruby/object:Gem::Version
27
+ hash: 11
28
+ segments:
29
+ - 0
30
+ - 5
31
+ - 0
32
+ version: 0.5.0
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: rspec-rails
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :development
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: shoulda
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :development
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: bundler
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ~>
70
+ - !ruby/object:Gem::Version
71
+ hash: 23
72
+ segments:
73
+ - 1
74
+ - 0
75
+ - 0
76
+ version: 1.0.0
77
+ type: :development
78
+ version_requirements: *id004
79
+ - !ruby/object:Gem::Dependency
80
+ name: jeweler
81
+ prerelease: false
82
+ requirement: &id005 !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ~>
86
+ - !ruby/object:Gem::Version
87
+ hash: 7
88
+ segments:
89
+ - 1
90
+ - 5
91
+ - 2
92
+ version: 1.5.2
93
+ type: :development
94
+ version_requirements: *id005
95
+ - !ruby/object:Gem::Dependency
96
+ name: rcov
97
+ prerelease: false
98
+ requirement: &id006 !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ hash: 3
104
+ segments:
105
+ - 0
106
+ version: "0"
107
+ type: :development
108
+ version_requirements: *id006
109
+ description: I18n InlineForms backend. Allows to store translations in a database using InlineForms, e.g. for providing a web-interface for managing translations. Forked from i18n-active_record by Sven Fuchs.
110
+ email: ace@suares.com
111
+ executables: []
112
+
113
+ extensions: []
114
+
115
+ extra_rdoc_files: []
116
+
117
+ files:
118
+ - Gemfile
119
+ - Gemfile.lock
120
+ - MIT-LICENSE
121
+ - README
122
+ - README.textile
123
+ - Rakefile
124
+ - i18n-inline_forms.gemspec
125
+ - lib/i18n/backend/inline_forms.rb
126
+ - lib/i18n/backend/inline_forms/missing.rb
127
+ - lib/i18n/backend/inline_forms/store_procs.rb
128
+ - lib/i18n/backend/inline_forms/translation.rb
129
+ - lib/i18n/inline_forms.rb
130
+ - lib/i18n/inline_forms/version.rb
131
+ - test/all.rb
132
+ - test/api_test.rb
133
+ - test/inline_forms_test.rb
134
+ - test/missing_test.rb
135
+ - test/test_helper.rb
136
+ - test/test_setup.rb
137
+ homepage: http://github.com/acesuares/i18n-inline_forms
138
+ licenses: []
139
+
140
+ post_install_message:
141
+ rdoc_options: []
142
+
143
+ require_paths:
144
+ - lib
145
+ required_ruby_version: !ruby/object:Gem::Requirement
146
+ none: false
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ hash: 3
151
+ segments:
152
+ - 0
153
+ version: "0"
154
+ required_rubygems_version: !ruby/object:Gem::Requirement
155
+ none: false
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ hash: 3
160
+ segments:
161
+ - 0
162
+ version: "0"
163
+ requirements: []
164
+
165
+ rubyforge_project: i18n-inline_forms
166
+ rubygems_version: 1.8.15
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: I18n InlineForms backend
170
+ test_files: []
171
+