babylonia 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a13bf3ea4fe0951e8ee79c6a22787739541c1225
4
- data.tar.gz: f92431777d5a4df6fb6068ec6c4fbd37a5703d37
3
+ metadata.gz: 7ec84f550c2f0845d6b9a2b16ede6c04dcd8db75
4
+ data.tar.gz: e181bce61c3a830c95017a9464577a602a3917e9
5
5
  SHA512:
6
- metadata.gz: e61ded2cb171b09824548fb281b768ae98d6a8289618613607cd37af950fb7876ed8046ece7cbe6f5c2c87ee2a70ef8ebc1094a447b07e9c706af395800d1257
7
- data.tar.gz: 3d434f2287d4e7da7c80af4815fc00a3faae7f866c39b0b3ad079fb4c7dd5a077d023094fb486905370cd5e723b248a84abbdb83497c8979f9116534c68959aa
6
+ metadata.gz: bf514ab66051cf4c21a6068df9c2dba0bd6eeb41acddf838a32f03d4aae9a3ed6df0e990d05efab0560ecc09abe74a6f7c62006958edd3c458d9d8e011ea3346
7
+ data.tar.gz: cdb741ec672ca3f50c4072193c1d392ff9240a5a8fda1e9d44ced1001dbbd84b1c383cd518a0eaf438081ab23c32801363ef5a2cde7623efadd889bfbbf6e996
data/.gitignore CHANGED
@@ -1,3 +1,4 @@
1
+ Gemfile.lock
1
2
  *.gem
2
3
  *.rbc
3
4
  .bundle
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ babylonia
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.0
data/.travis.yml CHANGED
@@ -1,6 +1,5 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.2
4
3
  - 1.9.3
5
4
  - 2.0.0
6
5
  - rbx-19mode
data/Gemfile CHANGED
@@ -3,6 +3,7 @@ source "http://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  group :development do
6
+ gem "rake"
6
7
  gem "yard", ">= 0.7.4"
7
8
  gem "bundler", ">= 1.0.0"
8
9
  end
data/Rakefile ADDED
@@ -0,0 +1,19 @@
1
+ # encoding: utf-8
2
+
3
+ require 'rubygems'
4
+ require 'bundler'
5
+ begin
6
+ Bundler.require(:default, :test)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+ require 'rake'
13
+ require 'rspec/core/rake_task'
14
+
15
+ task :default => :test
16
+
17
+ RSpec::Core::RakeTask.new(:spec) do |spec|
18
+ spec.pattern = FileList['spec/**/*_spec.rb']
19
+ end
@@ -1,13 +1,44 @@
1
1
  require 'yaml'
2
2
  require 'i18n'
3
3
 
4
+ # Let your users translate their content into their languages without additional tables or columns in your tables
5
+ # @author Beat Richartz
6
+ # @version 0.0.2
7
+ # @since 0.0.1
8
+ #
4
9
  module Babylonia
10
+
11
+ # Class methods to extend a class with in order to make it able to handle translatable attributes
12
+ #
5
13
  module ClassMethods
6
14
 
15
+ private
16
+
17
+ def add_to_handled_babylonian_fields data
18
+ instance_variable_set(:@handled_babylonian_fields, (instance_variable_get(:@handled_babylonian_fields) || []) + data.map(&:to_sym))
19
+ end
20
+
21
+ public
22
+ # Store all handled fields in a class instance variable
23
+ #
24
+ def handled_babylonian_fields
25
+ instance_variable_get(:@handled_babylonian_fields) || instance_variable_set(:@handled_babylonian_fields, [])
26
+ end
27
+ # Main class method ob Babylonia. Use to make attributes translatable
28
+ # @param [Symbol] fields the attributes to translate
29
+ # @param [Hash] options The options for translation
30
+ # @option [Symbol, Proc, String] locale The current locale - can be either a symbol that will be sent to the instance, a locale symbol that is included in available_locales or a proc that will get called with the instance and the attribute name. Defaults to I18n.locale at the time of use
31
+ # @option [Symbol, Proc, String] default_locale The fallback / default locale - can be either a symbol that will be sent to the instance, a locale symbol that is included in available_locales, a proc that will get called with the instance and the attribute name
32
+ # @option [Symbol, Proc, Array] available_locales The available locales - can be either a symbol that will be sent to the instance, a proc that will get called with the instance and the attribute name, or an Array of symbols of available locales. Defaults to I18n.available_locales at the time of use.
33
+ # @option [Boolean] fallback Wheter to fallback to the default locale or not
34
+ # @option [String] placeholder The placeholder to use for missing translations
35
+ #
7
36
  def build_babylonian_tower_on(*fields)
8
37
  babylonian_options = fields.last.is_a?(Hash) ? fields.pop : {}
38
+ add_to_handled_babylonian_fields fields
9
39
  babylonian_options[:locale] ||= lambda { |r, f| I18n.locale }
10
40
  babylonian_options[:default_locale] ||= lambda { |r, f| I18n.default_locale }
41
+ babylonian_options[:available_locales] ||= lambda { |r, f| I18n.available_locales }
11
42
  babylonian_options[:fallback] = true if babylonian_options[:fallback].nil?
12
43
 
13
44
  fields.each do |field|
@@ -43,6 +74,24 @@ module Babylonia
43
74
  send(:"#{field}_hash").keys
44
75
  end
45
76
 
77
+ define_method :has_translated_attribute? do |attr|
78
+ self.class.handled_babylonian_fields.include?(attr.to_sym)
79
+ end
80
+
81
+ # Return if a translation in the language is stored for the field
82
+ # @return [Boolean] True if a translation is stored
83
+ #
84
+ define_method :"#{field}_has_locale?" do |locale|
85
+ send(:"#{field}_languages").include?(locale.to_sym)
86
+ end
87
+
88
+ # Return if a locale is theoretically available for the field
89
+ # @return [Boolean] True if the language is available
90
+ #
91
+ define_method :"#{field}_has_available_locale?" do |locale|
92
+ evaluate_babylonian_option!(:available_locales, field).include?(locale.to_sym)
93
+ end
94
+
46
95
  # Set the field to a value. This either takes a string or a hash
47
96
  # If given a String, the current locale is set to this value
48
97
  # If given a Hash, the hash is merged into the current translation hash, and empty values are purged
@@ -58,6 +107,7 @@ module Babylonia
58
107
  if data.is_a?(String)
59
108
  current_hash.merge! evaluate_babylonian_option!(:locale, field) => data
60
109
  elsif data.is_a?(Hash)
110
+ data.delete_if{|k,v| !send(:"#{field}_has_available_locale?", k) }
61
111
  current_hash.merge! data
62
112
  end
63
113
 
@@ -67,13 +117,22 @@ module Babylonia
67
117
  alias_method :"#{field}=", :"#{field}_translated="
68
118
  end
69
119
 
70
- define_method :evaluate_babylonian_option! do |option, field|
120
+ # Define method missing to be able to access a language directly
121
+ define_method :method_missing do |meth, *args, &block|
122
+ if (m = meth.to_s.match(/\A([^_]+)_(\w+)(=)?\z/).to_a[1..3]) && has_translated_attribute?(m[0]) && send(:"#{m[0]}_has_available_locale?", m[1])
123
+ send(m[0] + m[2].to_s, m[2] ? {m[1].to_sym => args.first} : m[1].to_sym)
124
+ else
125
+ super(meth, *args, &block)
126
+ end
127
+ end
128
+
129
+ define_method :evaluate_babylonian_option! do |option, field, recursion=false|
71
130
  options = self.class.instance_variable_get :"@babylonian_options_for_#{field}"
72
131
 
73
132
  o = options[option]
74
- if o.is_a? Proc
133
+ if o.is_a?(Proc)
75
134
  o.call self, field
76
- elsif o.is_a? Symbol
135
+ elsif o.is_a?(Symbol) && (recursion || !evaluate_babylonian_option!(:available_locales, field, true).include?(o))
77
136
  send o
78
137
  else
79
138
  o
@@ -1,3 +1,5 @@
1
1
  module Babylonia
2
- VERSION = '0.0.2'
2
+ # The current gem version
3
+ #
4
+ VERSION = '0.0.3'
3
5
  end
@@ -8,7 +8,7 @@ describe Babylonia::ClassMethods do
8
8
  attr_accessor :marshes, :grasslands, :desert, :sky
9
9
 
10
10
  build_babylonian_tower_on :marshes
11
- build_babylonian_tower_on :grasslands, locales: %i(pi de en), locale: :architects_tongue, default_locale: lambda {|r, f| r.builders_tongue || :en }
11
+ build_babylonian_tower_on :grasslands, available_locales: [:pi, :de, :en, :it], locale: :architects_tongue, default_locale: lambda {|r, f| r.builders_tongue || :en }
12
12
  build_babylonian_tower_on :desert, :sky, fallback: false, placeholder: lambda {|r, field| "<span class='missing translation'>Translation missing for " + field.to_s + "</span>"}
13
13
 
14
14
  def architects_tongue
@@ -23,7 +23,7 @@ describe Babylonia::ClassMethods do
23
23
  context "without options" do
24
24
  subject { BabylonianFields.new }
25
25
  before(:each) do
26
- I18n.stub locale: :en, default_locale: :de
26
+ I18n.stub locale: :en, default_locale: :de, available_locales: [:de, :en, :it]
27
27
  end
28
28
 
29
29
  describe "#marshes" do
@@ -72,6 +72,50 @@ describe Babylonia::ClassMethods do
72
72
  end
73
73
  end
74
74
  end
75
+ describe "methods via method missing" do
76
+ context "getters" do
77
+ context "with the missing method matching the pattern FIELD_LANGUAGE" do
78
+ let(:meth) { :marshes_en }
79
+ it "should call the attribute method with an argument" do
80
+ subject.should_receive(:marshes).with(:en).once
81
+ subject.send(meth)
82
+ end
83
+ end
84
+ context "with the missing method not matching the pattern" do
85
+ let(:meth) { :marshes_something_else_entirely }
86
+ it "should raise Method Missing" do
87
+ lambda { subject.send(meth) }.should raise_error(NoMethodError)
88
+ end
89
+ end
90
+ context "with the missing method matching the pattern but an unavailable language" do
91
+ let(:meth) { :marshes_he }
92
+ it "should raise Method Missing" do
93
+ lambda { subject.send(meth) }.should raise_error(NoMethodError)
94
+ end
95
+ end
96
+ end
97
+ context "setters" do
98
+ context "with the missing method matching the pattern FIELD_LANGUAGE=" do
99
+ let(:meth) { :marshes_en= }
100
+ it "should call the attribute method with an argument" do
101
+ subject.should_receive(:marshes=).with(en: 'DATA').once
102
+ subject.send(meth, 'DATA')
103
+ end
104
+ end
105
+ context "with the missing method not matching the pattern" do
106
+ let(:meth) { :marshes_something_else_entirely }
107
+ it "should raise Method Missing" do
108
+ lambda { subject.send(meth) }.should raise_error(NoMethodError)
109
+ end
110
+ end
111
+ context "with the missing method matching the pattern but an unavailable language" do
112
+ let(:meth) { :marshes_he }
113
+ it "should raise Method Missing" do
114
+ lambda { subject.send(meth) }.should raise_error(NoMethodError)
115
+ end
116
+ end
117
+ end
118
+ end
75
119
  describe "marshes=" do
76
120
  context "with no existing data" do
77
121
  context "with a string" do
@@ -126,7 +170,7 @@ describe Babylonia::ClassMethods do
126
170
  subject.marshes_raw = "---\n:it: SOME ITALIAN\n:en: SOME ENGLISH\n:de: SOME DEUTSCH\n"
127
171
  end
128
172
  it "should return the translated languages of the field" do
129
- subject.marshes_languages.sort.should == %i(de en it)
173
+ subject.marshes_languages.sort.should == [:de, :en, :it]
130
174
  end
131
175
  end
132
176
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: babylonia
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Beat Richartz
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-19 00:00:00.000000000 Z
11
+ date: 2013-11-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: i18n
@@ -47,11 +47,13 @@ extra_rdoc_files: []
47
47
  files:
48
48
  - .gitignore
49
49
  - .rspec
50
+ - .ruby-gemset
51
+ - .ruby-version
50
52
  - .travis.yml
51
53
  - Gemfile
52
- - Gemfile.lock
53
54
  - LICENSE
54
55
  - README.rdoc
56
+ - Rakefile
55
57
  - babylonia.gemspec
56
58
  - lib/babylonia.rb
57
59
  - lib/babylonia/class_methods.rb
data/Gemfile.lock DELETED
@@ -1,29 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- babylonia (0.0.1)
5
- i18n (>= 0.5.0)
6
-
7
- GEM
8
- remote: http://rubygems.org/
9
- specs:
10
- diff-lcs (1.2.5)
11
- i18n (0.6.5)
12
- rspec (2.14.1)
13
- rspec-core (~> 2.14.0)
14
- rspec-expectations (~> 2.14.0)
15
- rspec-mocks (~> 2.14.0)
16
- rspec-core (2.14.7)
17
- rspec-expectations (2.14.4)
18
- diff-lcs (>= 1.1.3, < 2.0)
19
- rspec-mocks (2.14.4)
20
- yard (0.8.7.3)
21
-
22
- PLATFORMS
23
- ruby
24
-
25
- DEPENDENCIES
26
- babylonia!
27
- bundler (>= 1.0.0)
28
- rspec
29
- yard (>= 0.7.4)