multilang 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -0,0 +1,3 @@
1
+ module Multilang
2
+ VERSION = '0.0.1'
3
+ end
@@ -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
@@ -0,0 +1 @@
1
+ module ForTest end
@@ -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
@@ -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: