multilang 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +93 -0
- data/Rakefile +26 -0
- data/lib/multilang.rb +53 -0
- data/lib/multilang/language_names.rb +41 -0
- data/lib/multilang/language_names.yaml +1155 -0
- data/lib/multilang/slot.rb +71 -0
- data/lib/multilang/version.rb +3 -0
- data/multilang.gemspec +22 -0
- data/spec/for_test.rb +1 -0
- data/spec/for_test2.rb +1 -0
- data/spec/multilang/language_names_spec.rb +20 -0
- data/spec/multilang/slot_spec.rb +71 -0
- data/spec/multilang_spec.rb +106 -0
- data/spec/spec_helper.rb +29 -0
- metadata +101 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'multilang/language_names'
|
2
|
+
|
3
|
+
module Multilang
|
4
|
+
class Slot
|
5
|
+
def initialize
|
6
|
+
@items = {}
|
7
|
+
end
|
8
|
+
|
9
|
+
# Register the object to the slot.
|
10
|
+
#
|
11
|
+
# @param [String, Symbol] language_spec the language specifier
|
12
|
+
# @param [Object] object object to register
|
13
|
+
# @yield called once at getting the object first
|
14
|
+
#
|
15
|
+
# @see Multilang::Slot#[]
|
16
|
+
def register(language_spec, object, &first)
|
17
|
+
item = {:object => object}
|
18
|
+
item[:first] = first if first
|
19
|
+
@items[LanguageNames[language_spec]] = item
|
20
|
+
end
|
21
|
+
|
22
|
+
# Determine if registered with the language specifier in the slot.
|
23
|
+
#
|
24
|
+
# @param [String, Symbol] language_spec the language specifier
|
25
|
+
# @return whether registered with the language specifier in the slot
|
26
|
+
def exists?(language_spec)
|
27
|
+
!!@items[LanguageNames[language_spec]]
|
28
|
+
end
|
29
|
+
|
30
|
+
# Get the object by the language specifier. And call once the block that was
|
31
|
+
# given at registration the object.
|
32
|
+
#
|
33
|
+
# @param [String, Symbol] language_spec the language specifier
|
34
|
+
# @return [Object] registered object in the slot
|
35
|
+
#
|
36
|
+
# @see Multilang::Slot#register
|
37
|
+
def [](language_spec)
|
38
|
+
language_name = LanguageNames[language_spec]
|
39
|
+
raise ArgumentError, "#{language_spec.inspect} does not register" unless @items.key?(language_name)
|
40
|
+
item = @items[language_name]
|
41
|
+
|
42
|
+
if item[:first]
|
43
|
+
item[:first].call
|
44
|
+
item.delete(:first)
|
45
|
+
end
|
46
|
+
|
47
|
+
item[:object]
|
48
|
+
end
|
49
|
+
|
50
|
+
module Access
|
51
|
+
|
52
|
+
# @attribute [r] slot
|
53
|
+
# @return [Multilang::Slot] slot that is bound to class or module
|
54
|
+
def slot
|
55
|
+
instance_variable_get(Multilang::SLOT_KEY)
|
56
|
+
end
|
57
|
+
|
58
|
+
# Get registered object in the slot.
|
59
|
+
#
|
60
|
+
# @param [String, Symbol] language_spec
|
61
|
+
# @return [Object] registered object to the slot
|
62
|
+
#
|
63
|
+
# @see Multilang::Slot::Access#slot
|
64
|
+
# @see Multilang::Slot#[]
|
65
|
+
def [](language_spec)
|
66
|
+
slot[language_spec]
|
67
|
+
end
|
68
|
+
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/multilang.gemspec
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'multilang/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |gem|
|
7
|
+
gem.name = 'multilang'
|
8
|
+
gem.version = Multilang::VERSION
|
9
|
+
gem.authors = ['Takahiro Kondo']
|
10
|
+
gem.email = ['heartery@gmail.com']
|
11
|
+
gem.description = %q{Support multilingualization}
|
12
|
+
gem.summary = %q{Foundation for multilingualization}
|
13
|
+
gem.homepage = ''
|
14
|
+
|
15
|
+
gem.files = `git ls-files`.split($/)
|
16
|
+
gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
|
17
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
18
|
+
gem.require_paths = ['lib']
|
19
|
+
|
20
|
+
gem.add_development_dependency('rspec')
|
21
|
+
gem.add_development_dependency('nokogiri')
|
22
|
+
end
|
data/spec/for_test.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
module ForTest end
|
data/spec/for_test2.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
module ForTest2 end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'multilang/language_names'
|
2
|
+
|
3
|
+
describe Multilang::LanguageNames, '.#[]' do
|
4
|
+
it 'returns normalized language name if the language specifier is string' do
|
5
|
+
described_class['english'].should == 'English'
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'returns language name if the language specifier is symbol' do
|
9
|
+
described_class[:en ].should == 'English'
|
10
|
+
described_class[:eng].should == 'English'
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'raises TypeError if the language specifier is not string and symbol' do
|
14
|
+
lambda { described_class[1] }.should raise_error(TypeError, "can't convert Fixnum into String or Symbol")
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'raises ArgumentError if the language specifier does not exist' do
|
18
|
+
lambda { described_class['unknown'] }.should raise_error(ArgumentError, '"unknown" language specifier does not defined')
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'multilang/slot'
|
3
|
+
|
4
|
+
describe Multilang::Slot, '#register' do
|
5
|
+
before do
|
6
|
+
@slot = described_class.new
|
7
|
+
end
|
8
|
+
|
9
|
+
it 'registers the object to the slot' do
|
10
|
+
object = Object.new
|
11
|
+
@slot.register(:en, object)
|
12
|
+
@slot.should be_exists('English')
|
13
|
+
@slot['English'].should == object
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe Multilang::Slot, '#[]' do
|
18
|
+
before do
|
19
|
+
@slot = described_class.new
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'returns registered object' do
|
23
|
+
object = Object.new
|
24
|
+
@slot.register(:en, object)
|
25
|
+
@slot['English'].should == object
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'calls the block once if gives a block at construction' do
|
29
|
+
count = 0
|
30
|
+
@slot.register(:en, Object.new) { count += 1 }
|
31
|
+
@slot['English']
|
32
|
+
count.should == 1
|
33
|
+
@slot['English']
|
34
|
+
count.should == 1
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'raises ArgumentError if the language specifier does not register to the slot' do
|
38
|
+
lambda { @slot[:en] }.should raise_error(ArgumentError, ':en does not register')
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
describe Multilang::Slot::Access, '#slot' do
|
43
|
+
before do
|
44
|
+
@slot = slot_stub
|
45
|
+
@class = Class.new
|
46
|
+
@class.extend(described_class)
|
47
|
+
@class.instance_variable_set(Multilang::SLOT_KEY, @slot)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'returns the value of instance variable named with Multilang::SLOT_KEY' do
|
51
|
+
@class.slot.should == @slot
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe Multilang::Slot::Access, '#[]' do
|
56
|
+
before do
|
57
|
+
@slot = slot_stub
|
58
|
+
@class = Class.new
|
59
|
+
@class.extend(described_class)
|
60
|
+
@class.instance_variable_set(Multilang::SLOT_KEY, @slot)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'calls #[] of the slot with the language specifier' do
|
64
|
+
@class.slot.should_receive(:[]).with('English')
|
65
|
+
@class['English']
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'returns the return value from #[] of the slot' do
|
69
|
+
@class['English'].should == 'item for English'
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,106 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'multilang'
|
3
|
+
|
4
|
+
describe Multilang, '.#register' do
|
5
|
+
before do
|
6
|
+
define_const Class, 'SampleClass::English'
|
7
|
+
define_const Module, 'SampleModule::English'
|
8
|
+
end
|
9
|
+
|
10
|
+
after do
|
11
|
+
remove_const 'SampleClass::English'
|
12
|
+
remove_const 'SampleModule::English'
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'extends parent class (parent class of Foo::Bar::Baz is Foo::Bar)' do
|
16
|
+
described_class.register SampleClass::English
|
17
|
+
SampleClass.should be_respond_to(:slot)
|
18
|
+
SampleClass.should be_respond_to(:[])
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'extends parent module' do
|
22
|
+
described_class.register SampleModule::English
|
23
|
+
SampleModule.should be_respond_to(:slot)
|
24
|
+
SampleModule.should be_respond_to(:[])
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'registers to the slot' do
|
28
|
+
described_class.register SampleClass::English
|
29
|
+
SampleClass.slot.should be_exists('English')
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'raises TypeError if gives non-module' do
|
33
|
+
lambda { described_class.register 1 }.should raise_error(TypeError, "can't convert Fixnum into Module")
|
34
|
+
lambda { described_class.register 'English' }.should raise_error(TypeError, "can't convert String into Module")
|
35
|
+
lambda { described_class.register SampleClass::English }.should_not raise_error(TypeError)
|
36
|
+
lambda { described_class.register SampleModule::English }.should_not raise_error(TypeError)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises ArgumentError if gives anonymous class' do
|
40
|
+
lambda { described_class.register Class.new }.should raise_error(ArgumentError, "anonymous class can't register")
|
41
|
+
lambda { described_class.register SampleClass::English }.should_not raise_error(ArgumentError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises ArgumentError if gives anonymous module' do
|
45
|
+
lambda { described_class.register Module.new }.should raise_error(ArgumentError, "anonymous module can't register")
|
46
|
+
lambda { described_class.register SampleModule::English }.should_not raise_error(ArgumentError)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'raises ArgumentError if gives top-level class' do
|
50
|
+
lambda { described_class.register SampleClass }.should raise_error(ArgumentError, "can't permit top-level class")
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'raises ArgumentError if gives top-level module' do
|
54
|
+
lambda { described_class.register SampleModule }.should raise_error(ArgumentError, "can't permit top-level module")
|
55
|
+
end
|
56
|
+
|
57
|
+
context 'with :as option' do
|
58
|
+
before { define_const Class, 'SampleClass::E' }
|
59
|
+
after { remove_const 'SampleClass::E' }
|
60
|
+
|
61
|
+
it 'registers to the slot with the value of :as option' do
|
62
|
+
described_class.register SampleClass::E, :as => 'English'
|
63
|
+
SampleClass.slot.should be_exists('English')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context 'with :with option' do
|
68
|
+
it 'calls Kernel#.require with the value of :with option at initialization' do
|
69
|
+
Object.should_not be_const_defined(:ForTest)
|
70
|
+
described_class.register SampleClass::English, :with => 'for_test'
|
71
|
+
SampleClass['English']
|
72
|
+
Object.should be_const_defined(:ForTest)
|
73
|
+
end
|
74
|
+
|
75
|
+
context 'with a block' do
|
76
|
+
it 'considers both the value of :with option and the block' do
|
77
|
+
Object.should_not be_const_defined(:ForTest2)
|
78
|
+
passed = false
|
79
|
+
|
80
|
+
described_class.register SampleClass::English, :with => 'for_test2' do
|
81
|
+
passed = true
|
82
|
+
end
|
83
|
+
|
84
|
+
SampleClass['English']
|
85
|
+
Object.should be_const_defined(:ForTest2)
|
86
|
+
passed.should be_true
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
describe Multilang, ' including' do
|
93
|
+
before do
|
94
|
+
define_const Class, 'SampleClass::English'
|
95
|
+
end
|
96
|
+
|
97
|
+
after do
|
98
|
+
remove_const 'SampleClass::English'
|
99
|
+
end
|
100
|
+
|
101
|
+
it "calls #{described_class}.#register" do
|
102
|
+
described_class.should_receive(:register).with(SampleClass::English)
|
103
|
+
mod = described_class
|
104
|
+
SampleClass::English.class_eval { include mod }
|
105
|
+
end
|
106
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
def define_const(type, name)
|
2
|
+
klass = name.split('::').inject(Object) do |parent, name|
|
3
|
+
if parent.const_defined?(name)
|
4
|
+
parent.const_get(name)
|
5
|
+
else
|
6
|
+
parent.const_set(name, type.new)
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
def remove_const(name)
|
12
|
+
names = name.split('::')
|
13
|
+
|
14
|
+
parents = names[0..-2].inject([Object]) do |parents, name|
|
15
|
+
parents << parents.last.const_get(name)
|
16
|
+
end
|
17
|
+
|
18
|
+
names.reverse.each do |name|
|
19
|
+
parent = parents.pop
|
20
|
+
parent.class_eval { remove_const name }
|
21
|
+
break unless parent.constants.empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def slot_stub
|
26
|
+
stub.tap do |s|
|
27
|
+
s.stub!(:[]).and_return { |language_spec| "item for #{language_spec}" }
|
28
|
+
end
|
29
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: multilang
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Takahiro Kondo
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-06 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rspec
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: nokogiri
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
description: Support multilingualization
|
47
|
+
email:
|
48
|
+
- heartery@gmail.com
|
49
|
+
executables: []
|
50
|
+
extensions: []
|
51
|
+
extra_rdoc_files: []
|
52
|
+
files:
|
53
|
+
- .gitignore
|
54
|
+
- Gemfile
|
55
|
+
- LICENSE.txt
|
56
|
+
- README.md
|
57
|
+
- Rakefile
|
58
|
+
- lib/multilang.rb
|
59
|
+
- lib/multilang/language_names.rb
|
60
|
+
- lib/multilang/language_names.yaml
|
61
|
+
- lib/multilang/slot.rb
|
62
|
+
- lib/multilang/version.rb
|
63
|
+
- multilang.gemspec
|
64
|
+
- spec/for_test.rb
|
65
|
+
- spec/for_test2.rb
|
66
|
+
- spec/multilang/language_names_spec.rb
|
67
|
+
- spec/multilang/slot_spec.rb
|
68
|
+
- spec/multilang_spec.rb
|
69
|
+
- spec/spec_helper.rb
|
70
|
+
homepage: ''
|
71
|
+
licenses: []
|
72
|
+
post_install_message:
|
73
|
+
rdoc_options: []
|
74
|
+
require_paths:
|
75
|
+
- lib
|
76
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
77
|
+
none: false
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '0'
|
88
|
+
requirements: []
|
89
|
+
rubyforge_project:
|
90
|
+
rubygems_version: 1.8.24
|
91
|
+
signing_key:
|
92
|
+
specification_version: 3
|
93
|
+
summary: Foundation for multilingualization
|
94
|
+
test_files:
|
95
|
+
- spec/for_test.rb
|
96
|
+
- spec/for_test2.rb
|
97
|
+
- spec/multilang/language_names_spec.rb
|
98
|
+
- spec/multilang/slot_spec.rb
|
99
|
+
- spec/multilang_spec.rb
|
100
|
+
- spec/spec_helper.rb
|
101
|
+
has_rdoc:
|