couchrest_localised_properties 0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *.swp
2
+ *.gem
3
+ Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+
2
+ source :rubygems
3
+ gemspec
4
+
data/LICENSE ADDED
@@ -0,0 +1,16 @@
1
+ Copyright (c) 2007 Samuel Lown
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software
4
+ and associated documentation files (the “Software”), to deal in the Software without restriction,
5
+ including without limitation the rights to use, copy, modify, merge, publish, distribute,
6
+ sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
7
+ is furnished to do so, subject to the following conditions:
8
+
9
+ The above copyright notice and this permission notice shall be included in all copies or
10
+ substantial portions of the Software.
11
+
12
+ THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13
+ BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES
15
+ OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
16
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,61 @@
1
+ = CouchRest Localised Properties
2
+
3
+ Localise your CouchRest Model properties as if by magic!
4
+
5
+ == Introduction
6
+
7
+ Storing translations of data is always a difficult problem.
8
+
9
+ CouchRest Localised Properties works by overwriting the normal attribute getters and setters with special localised versions that will magically replace the attribute with a hash. For each locale supported by your application there will be a key in the hash to store the real value. This approach allows you to apply any typecasting to the value being read as if you were working in just one locale.
10
+
11
+ While getting and setting values is quite considerably easier, you'll still need to write your view methods manually.
12
+
13
+ == Basic Usage
14
+
15
+ class Article < CouchRest::Model::Base
16
+ localised_property :title, String
17
+ localised_property :content, String
18
+
19
+ property :published_at, DateTime
20
+ end
21
+
22
+ # set language to english and set title
23
+ I18n.default_locale = :en
24
+ I18n.locale = :en
25
+ @a = Article.new
26
+ @a.title = "Test Title"
27
+
28
+ # language changed to spanish:
29
+ I18n.locale = :es
30
+ # returns default text as no translation set
31
+ @a.title == "Test Title" # true
32
+
33
+ # set the title for spanish
34
+ @a.title = "Título de prueba"
35
+
36
+ # Have a look at the raw data
37
+ @a['title'] == {
38
+ 'en' => "Test Title",
39
+ 'es' => "Título de prueba"
40
+ }
41
+
42
+ == Updates
43
+
44
+ === v0.1 - 25th March 2011
45
+
46
+ - First release
47
+
48
+ == Todos / Bugs
49
+
50
+ - Please let me know!
51
+
52
+ == License
53
+
54
+ Copyright (c) 2011 Samuel Lown <me (AT) samlown.com>
55
+
56
+ This Plugin is released under the MIT license, as Rails itself. Please see the
57
+ attached LICENSE file for further details.
58
+
59
+ This document and plugin should be considered a work in progress until further
60
+ notice!
61
+
data/Rakefile ADDED
@@ -0,0 +1,32 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ Bundler::GemHelper.install_tasks
4
+
5
+ require 'rake'
6
+ require "rake/rdoctask"
7
+
8
+ require 'rspec'
9
+ require 'rspec/core/rake_task'
10
+
11
+ desc "Run all specs"
12
+ Rspec::Core::RakeTask.new(:spec) do |spec|
13
+ spec.rspec_opts = ["--color"]
14
+ spec.pattern = 'spec/**/*_spec.rb'
15
+ end
16
+
17
+ desc "Print specdocs"
18
+ Rspec::Core::RakeTask.new(:doc) do |spec|
19
+ spec.rspec_opts = ["--format", "specdoc"]
20
+ spec.pattern = 'spec/*_spec.rb'
21
+ end
22
+
23
+ desc "Generate the rdoc"
24
+ Rake::RDocTask.new do |rdoc|
25
+ files = ["README.rdoc", "LICENSE", "lib/**/*.rb"]
26
+ rdoc.rdoc_files.add(files)
27
+ rdoc.main = "README.rdoc"
28
+ rdoc.title = "CouchRest Localised Properties Extension"
29
+ end
30
+
31
+ desc "Run the rspec"
32
+ task :default => :spec
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1
@@ -0,0 +1,28 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{couchrest_localised_properties}
5
+ s.version = File.read(File.join(File.dirname(__FILE__), 'VERSION')).strip
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new("> 1.3.5") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Sam Lown"]
9
+ s.date = %q{2011-03-23}
10
+ s.description = %q{Add support to CouchRest Model for localised properties.}
11
+ s.email = %q{me@samlown.com}
12
+ s.extra_rdoc_files = [
13
+ "LICENSE",
14
+ "README.rdoc"
15
+ ]
16
+ s.homepage = %q{https://github.com/samlown/couchrest_localised_properties}
17
+ s.rubygems_version = %q{1.3.7}
18
+ s.summary = %q{Add support to CouchRest Model for localised properties.}
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
22
+ s.require_paths = ["lib"]
23
+
24
+ s.add_dependency("couchrest_model", "~> 1.1.0.beta")
25
+ s.add_dependency("i18n", "> 0.3.0")
26
+ s.add_development_dependency(%q<rspec>, ">= 2.0.0")
27
+ end
28
+
@@ -0,0 +1,81 @@
1
+ #
2
+ # CouchRest Localised Properties
3
+ #
4
+
5
+ require 'couchrest_model'
6
+
7
+ module CouchRest
8
+ module LocalisedProperties
9
+
10
+ extend ActiveSupport::Concern
11
+
12
+ def read_localised_attribute(property)
13
+ attr = (self[find_property!(property).to_s] || {})
14
+ attr[I18n.locale.to_s] || attr[I18n.default_locale.to_s]
15
+ end
16
+
17
+ def write_localised_attribute(property, value)
18
+ prop = find_property!(property)
19
+ key = prop.to_s
20
+ if value.is_a?(Hash) # from mass-asign
21
+ self[key] = value
22
+ self[key].each do |k,v|
23
+ self[key][k] = prop.cast(self, v)
24
+ end
25
+ else
26
+ self[key] ||= { }
27
+ self[key][I18n.locale.to_s] = prop.is_a?(String) ? value : prop.cast(self, value)
28
+ end
29
+ end
30
+
31
+ module ClassMethods
32
+
33
+ def localised_property(name, *options, &block)
34
+ # Create a normal property
35
+ p = property(name, *options, &block)
36
+ raise "Localised properties cannot be used with Hashes!" if p.type == Hash
37
+ # Override the normal methods with special accessors
38
+ create_localised_property_getter(p)
39
+ create_localised_property_setter(p)
40
+ end
41
+
42
+ protected
43
+
44
+ # defines the getter for the property (and optional aliases)
45
+ def create_localised_property_getter(property)
46
+ # meth = property.name
47
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
48
+ def #{property.name}
49
+ read_localised_attribute('#{property.name}')
50
+ end
51
+ EOS
52
+ if ['boolean', TrueClass.to_s.downcase].include?(property.type.to_s.downcase)
53
+ class_eval <<-EOS, __FILE__, __LINE__
54
+ def #{property.name}?
55
+ value = read_localised_attribute('#{property.name}')
56
+ !(value.nil? || value == false)
57
+ end
58
+ EOS
59
+ end
60
+ end
61
+
62
+ # defines the setter for the property (and optional aliases)
63
+ def create_localised_property_setter(property)
64
+ property_name = property.name
65
+ class_eval <<-EOS
66
+ def #{property_name}=(value)
67
+ write_localised_attribute('#{property_name}', value)
68
+ end
69
+ EOS
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+ end
76
+
77
+ # Add self to the CouchRest Model Base
78
+ CouchRest::Model::Base.class_eval do
79
+ include CouchRest::LocalisedProperties
80
+ end
81
+
@@ -0,0 +1,84 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ class Article < CouchRest::Model::Base
6
+ use_database DB
7
+ localised_property :title, String
8
+ localised_property :content, String
9
+ localised_property :active, TrueClass
10
+ property :posted_at, DateTime
11
+ timestamps!
12
+ end
13
+
14
+ I18n.default_locale = :en
15
+
16
+ describe "Basic Usage" do
17
+
18
+ before :each do
19
+ @a = Article.new
20
+ end
21
+
22
+ after :each do
23
+ @a.destroy
24
+ end
25
+
26
+ it "should be possible to set and receive basic attributes" do
27
+ @a.title = "This is a test title"
28
+ @a.content = "This is the body of the article."
29
+ @a.active = true
30
+ @a.posted_at = now = DateTime.current
31
+
32
+ @a.save
33
+
34
+ @a = Article.first
35
+ @a.title.should eql("This is a test title")
36
+ @a.active.should be_true
37
+ @a.posted_at.to_s.should eql(now.to_s)
38
+ end
39
+
40
+ it "should be possible to use default values" do
41
+ @a.title = "This is a test title"
42
+ @a.save
43
+ @a = Article.first
44
+ I18n.locale = :es
45
+ @a.title.should eql("This is a test title")
46
+ end
47
+
48
+ it "should be possible to set value for other language" do
49
+ I18n.locale = :en
50
+ @a.title = "This is a test title"
51
+ I18n.locale = :es
52
+ @a.title = "Una prueba en castellano de un título"
53
+ @a.save
54
+
55
+ @a = Article.first
56
+ @a.title.should eql("Una prueba en castellano de un título")
57
+ I18n.locale = :en
58
+ @a.title.should eql("This is a test title")
59
+ end
60
+
61
+ it "should allow mass-asignment" do
62
+ I18n.locale = :en
63
+
64
+ @a.attributes = {:title => "TITLE TEST", :content => 'The body', :posted_at => DateTime.current}
65
+
66
+ @a.title.should eql("TITLE TEST")
67
+ @a.save
68
+
69
+ @a = Article.first
70
+ I18n.locale = :es
71
+ @a.title.should eql("TITLE TEST")
72
+ @a.attributes = {:title => "PRUEBA DE TITULO"}
73
+ @a.save
74
+
75
+ @a = Article.first
76
+ @a.title.should eql('PRUEBA DE TITULO')
77
+ @a.content.should eql('The body')
78
+
79
+ I18n.locale = :en
80
+ @a.title.should eql('TITLE TEST')
81
+ end
82
+
83
+ end
84
+
@@ -0,0 +1,37 @@
1
+
2
+ # Spec preparations, copied from couchrest model
3
+
4
+ require "bundler/setup"
5
+ require "rubygems"
6
+ require "rspec"
7
+
8
+ require File.join(File.dirname(__FILE__), '..','lib','couchrest_localised_properties')
9
+ # check the following file to see how to use the spec'd features.
10
+
11
+ unless defined?(COUCHHOST)
12
+ COUCHHOST = "http://127.0.0.1:5984"
13
+ TESTDB = 'couchrest-localised-test'
14
+ TEST_SERVER = CouchRest.new COUCHHOST
15
+ TEST_SERVER.default_database = TESTDB
16
+ DB = TEST_SERVER.database(TESTDB)
17
+ end
18
+
19
+ class Basic < CouchRest::Model::Base
20
+ use_database TEST_SERVER.default_database
21
+ end
22
+
23
+ def reset_test_db!
24
+ DB.recreate! rescue nil
25
+ DB
26
+ end
27
+
28
+ RSpec.configure do |config|
29
+ config.before(:all) { reset_test_db! }
30
+ config.after(:all) do
31
+ cr = TEST_SERVER
32
+ test_dbs = cr.databases.select { |db| db =~ /^#{TESTDB}/ }
33
+ test_dbs.each do |db|
34
+ cr.database(db).delete! rescue nil
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,122 @@
1
+ # encoding: utf-8
2
+
3
+ require File.expand_path('../../spec_helper', __FILE__)
4
+
5
+ class BasicLP < CouchRest::Model::Base
6
+ use_database DB
7
+ localised_property :title, String
8
+ property :posted_at, DateTime
9
+ end
10
+
11
+ I18n.default_locale = :en
12
+
13
+ describe "CouchRest LocalisedProperties" do
14
+
15
+ describe "instance" do
16
+
17
+ before :each do
18
+ @obj = BasicLP.new
19
+ end
20
+
21
+ describe "#read_localised_attribute" do
22
+ before :each do
23
+ @obj['title'] = { 'en' => "Sample Title", 'es' => "Título de muestra" }
24
+ end
25
+
26
+ it "should read title appropriately" do
27
+ I18n.locale = :en
28
+ @obj.read_localised_attribute('title').should eql("Sample Title")
29
+ I18n.locale = 'es'
30
+ @obj.read_localised_attribute('title').should eql("Título de muestra")
31
+ end
32
+
33
+ it "should use default locale if no match available" do
34
+ I18n.locale = :de
35
+ @obj.read_localised_attribute('title').should eql('Sample Title')
36
+ end
37
+
38
+ it "should not cause any problems if data not set" do
39
+ @obj['title'] = nil
40
+ lambda { @obj.read_localised_attribute('title') }.should_not raise_error
41
+ end
42
+ end
43
+
44
+ describe "#write_localised_attribute" do
45
+ it "should write basic property" do
46
+ I18n.locale = 'en'
47
+ @obj.write_localised_attribute('title', "Sample Title")
48
+ @obj['title']['en'].should eql("Sample Title")
49
+ I18n.locale = 'es'
50
+ @obj.write_localised_attribute('title', "Ejemplo de un título")
51
+ @obj['title']['es'].should eql("Ejemplo de un título")
52
+ end
53
+
54
+ it "should allow mass-assignment with Hash" do
55
+ @obj.write_localised_attribute('title', {'en' => "Sample Title"})
56
+ @obj['title']['en'].should eql('Sample Title')
57
+ end
58
+
59
+ describe "with casting" do
60
+ before :each do
61
+ @prop = mock('Property')
62
+ @prop.should_receive(:to_s).and_return('title')
63
+ @prop.should_receive(:cast).and_return('the title')
64
+ @obj.should_receive(:find_property!).and_return(@prop)
65
+ end
66
+ it "should perform type casting on normal write" do
67
+ @prop.should_receive(:is_a?).and_return(false)
68
+ I18n.locale = 'en'
69
+ @obj.write_localised_attribute('title', 'something')
70
+ @obj['title']['en'].should eql('the title')
71
+ end
72
+ it "should perform casting on each key when hash sent" do
73
+ @prop.should_receive(:cast).and_return('the title') # second time
74
+ @obj.write_localised_attribute('title', {'en' => 'title', 'es' => 'título'})
75
+ end
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ describe "class methods" do
82
+
83
+ describe ".localised_property" do
84
+ it "should be added to class" do
85
+ BasicLP.respond_to?(:localised_property).should be_true
86
+ end
87
+
88
+ it "should call property method" do
89
+ prop = mock('Property')
90
+ prop.should_receive(:type).and_return(String)
91
+ BasicLP.should_receive(:property).with(:body).and_return(prop)
92
+ BasicLP.should_receive(:create_localised_property_getter)
93
+ BasicLP.should_receive(:create_localised_property_setter)
94
+ BasicLP.localised_property :body
95
+ end
96
+
97
+ it "should fail if type provided is a Hash" do
98
+ lambda { BasicLP.localised_property(:body, Hash) }.should raise_error
99
+ end
100
+
101
+ it "should create getters and setters" do
102
+ BasicLP.localised_property :active, TrueClass
103
+ @obj = BasicLP.new
104
+ @obj.respond_to?(:active).should be_true
105
+ @obj.respond_to?(:active?).should be_true
106
+ @obj.respond_to?(:active=).should be_true
107
+ end
108
+
109
+ it "getters and setters should pass on requests" do
110
+ BasicLP.localised_property :content, String
111
+ @obj = BasicLP.new
112
+ @obj.should_receive(:read_localised_attribute).with('content')
113
+ @obj.content
114
+ @obj.should_receive(:write_localised_attribute).with('content', 'foo')
115
+ @obj.content = 'foo'
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
metadata ADDED
@@ -0,0 +1,121 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: couchrest_localised_properties
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ version: "0.1"
9
+ platform: ruby
10
+ authors:
11
+ - Sam Lown
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+
16
+ date: 2011-03-23 00:00:00 +01:00
17
+ default_executable:
18
+ dependencies:
19
+ - !ruby/object:Gem::Dependency
20
+ name: couchrest_model
21
+ prerelease: false
22
+ requirement: &id001 !ruby/object:Gem::Requirement
23
+ none: false
24
+ requirements:
25
+ - - ~>
26
+ - !ruby/object:Gem::Version
27
+ segments:
28
+ - 1
29
+ - 1
30
+ - 0
31
+ - beta
32
+ version: 1.1.0.beta
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: i18n
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">"
42
+ - !ruby/object:Gem::Version
43
+ segments:
44
+ - 0
45
+ - 3
46
+ - 0
47
+ version: 0.3.0
48
+ type: :runtime
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: rspec
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ segments:
59
+ - 2
60
+ - 0
61
+ - 0
62
+ version: 2.0.0
63
+ type: :development
64
+ version_requirements: *id003
65
+ description: Add support to CouchRest Model for localised properties.
66
+ email: me@samlown.com
67
+ executables: []
68
+
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - LICENSE
73
+ - README.rdoc
74
+ files:
75
+ - .gitignore
76
+ - Gemfile
77
+ - LICENSE
78
+ - README.rdoc
79
+ - Rakefile
80
+ - VERSION
81
+ - couchrest_localised_properties.gemspec
82
+ - lib/couchrest_localised_properties.rb
83
+ - spec/scenario/localise_properties_spec.rb
84
+ - spec/spec_helper.rb
85
+ - spec/unit/couchrest_localised_properties_spec.rb
86
+ has_rdoc: true
87
+ homepage: https://github.com/samlown/couchrest_localised_properties
88
+ licenses: []
89
+
90
+ post_install_message:
91
+ rdoc_options: []
92
+
93
+ require_paths:
94
+ - lib
95
+ required_ruby_version: !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ segments:
101
+ - 0
102
+ version: "0"
103
+ required_rubygems_version: !ruby/object:Gem::Requirement
104
+ none: false
105
+ requirements:
106
+ - - ">"
107
+ - !ruby/object:Gem::Version
108
+ segments:
109
+ - 1
110
+ - 3
111
+ - 5
112
+ version: 1.3.5
113
+ requirements: []
114
+
115
+ rubyforge_project:
116
+ rubygems_version: 1.3.7
117
+ signing_key:
118
+ specification_version: 3
119
+ summary: Add support to CouchRest Model for localised properties.
120
+ test_files: []
121
+