proxy_for_template 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +4 -0
- data/lib/proxy_for_template/version.rb +3 -0
- data/lib/proxy_for_template.rb +117 -0
- data/proxy_for_template.gemspec +28 -0
- data/spec/activerecord_spec.rb +114 -0
- data/spec/proxy_spec.rb +103 -0
- data/spec/spec_helper.rb +8 -0
- metadata +149 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require "proxy_for_template/version"
|
2
|
+
|
3
|
+
module ProxyForTemplate
|
4
|
+
|
5
|
+
module ClassMethods
|
6
|
+
|
7
|
+
def templated_methods
|
8
|
+
@templated_methods ||= Set.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def template_accessor(*method_names)
|
12
|
+
method_names.each do |method|
|
13
|
+
attr_accessor method
|
14
|
+
define_proxy method
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def template_method(*method_names)
|
19
|
+
method_names.each do |method|
|
20
|
+
define_proxy(method)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def within_rails?
|
25
|
+
@rails ||= defined?(ActiveRecord::Base)
|
26
|
+
end
|
27
|
+
|
28
|
+
def define_proxy(method_name)
|
29
|
+
templated_methods << method_name
|
30
|
+
|
31
|
+
define_attribute_methods if respond_to?(:define_attribute_methods)
|
32
|
+
|
33
|
+
read_method = method_name.to_s
|
34
|
+
|
35
|
+
define_proxy_read_method(read_method)
|
36
|
+
end
|
37
|
+
|
38
|
+
def define_proxy_read_method(method_name)
|
39
|
+
read_method = method_name.to_s
|
40
|
+
|
41
|
+
alias_method read_method + '_orig', read_method
|
42
|
+
|
43
|
+
define_method(read_method) do
|
44
|
+
proxy_read(read_method)
|
45
|
+
end
|
46
|
+
|
47
|
+
if(within_rails?)
|
48
|
+
define_method(read_method + '_before_type_cast') do
|
49
|
+
proxy_attribute_read(read_method)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.included(base)
|
56
|
+
base.extend(ClassMethods)
|
57
|
+
end
|
58
|
+
|
59
|
+
def template_takes_precedence(method)
|
60
|
+
true
|
61
|
+
end
|
62
|
+
|
63
|
+
def templated_methods
|
64
|
+
self.class.templated_methods
|
65
|
+
end
|
66
|
+
|
67
|
+
def proxy_attribute_read(method)
|
68
|
+
|
69
|
+
template_value = nil
|
70
|
+
self_value = nil
|
71
|
+
|
72
|
+
if(template_responds_to?(method))
|
73
|
+
template_value = template.attributes[method]
|
74
|
+
end
|
75
|
+
|
76
|
+
self_value = self.attributes[method]
|
77
|
+
|
78
|
+
if template_takes_precedence(method) && !(template_value.nil? || template_value == '')
|
79
|
+
self_value = template_value
|
80
|
+
end
|
81
|
+
|
82
|
+
self_value
|
83
|
+
end
|
84
|
+
|
85
|
+
def proxy_read(method)
|
86
|
+
|
87
|
+
template_value = nil
|
88
|
+
self_value = nil
|
89
|
+
|
90
|
+
if(template_responds_to?(method))
|
91
|
+
template_value = template.send(method)
|
92
|
+
end
|
93
|
+
|
94
|
+
self_value = self.send(method + '_orig')
|
95
|
+
|
96
|
+
if template_takes_precedence(method) && !(template_value.nil? || template_value == '')
|
97
|
+
self_value = template_value
|
98
|
+
end
|
99
|
+
|
100
|
+
self_value
|
101
|
+
end
|
102
|
+
|
103
|
+
def templated?(method)
|
104
|
+
value = nil
|
105
|
+
|
106
|
+
if(templated_methods.include?(method) && template_responds_to?(method))
|
107
|
+
value = template.send(method)
|
108
|
+
end
|
109
|
+
|
110
|
+
blank = (value.nil? || value == '')
|
111
|
+
!blank
|
112
|
+
end
|
113
|
+
|
114
|
+
def template_responds_to?(method)
|
115
|
+
(respond_to?(:template) && template && template.respond_to?(method))
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "proxy_for_template/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "proxy_for_template"
|
7
|
+
s.version = ProxyForTemplate::VERSION
|
8
|
+
s.authors = ["Mike Emery"]
|
9
|
+
s.email = ["philodoxx@gmail.com"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Allows method calls to be delegated to a template object.}
|
12
|
+
s.description = %q{Allows method calls to be delegated to a template object.}
|
13
|
+
|
14
|
+
s.rubyforge_project = "proxy_for_template"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
s.add_development_dependency "rspec"
|
23
|
+
s.add_development_dependency "activerecord", '~> 2.3.10'
|
24
|
+
s.add_development_dependency "actionpack", '~> 2.3.10'
|
25
|
+
s.add_development_dependency "sqlite3"
|
26
|
+
s.add_development_dependency "database_cleaner"
|
27
|
+
# s.add_runtime_dependency "rest-client"
|
28
|
+
end
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_record'
|
3
|
+
require 'action_view'
|
4
|
+
require 'action_pack'
|
5
|
+
require 'database_cleaner'
|
6
|
+
|
7
|
+
DatabaseCleaner.strategy = :truncation
|
8
|
+
|
9
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
|
10
|
+
|
11
|
+
ActiveRecord::Base.logger
|
12
|
+
ActiveRecord::Schema.define(:version => 1) do
|
13
|
+
create_table :sporks do |t|
|
14
|
+
t.integer :some_value
|
15
|
+
t.references :template_id
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class Spork < ActiveRecord::Base
|
20
|
+
belongs_to :template, :class_name => Spork.name
|
21
|
+
include ProxyForTemplate
|
22
|
+
|
23
|
+
attr_accessor :template_takes_precedence
|
24
|
+
|
25
|
+
def template_takes_precedence(method)
|
26
|
+
@template_takes_precedence.nil? ? true : @template_takes_precedence
|
27
|
+
end
|
28
|
+
|
29
|
+
template_method :some_value
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ProxyForTemplate, '#activerecord' do
|
33
|
+
|
34
|
+
include ActionView::Helpers
|
35
|
+
|
36
|
+
before(:each) do
|
37
|
+
DatabaseCleaner.clean
|
38
|
+
end
|
39
|
+
|
40
|
+
after(:all) do
|
41
|
+
ActiveRecord::Base.connection.tables.each do |table|
|
42
|
+
ActiveRecord::Base.connection.drop_table(table)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should still work if the template is nil" do
|
47
|
+
base = Spork.create(:some_value => 5)
|
48
|
+
|
49
|
+
base.some_value.should eq(5)
|
50
|
+
end
|
51
|
+
|
52
|
+
it "returns the template's property if it exists" do
|
53
|
+
template = Spork.create(:some_value => 10)
|
54
|
+
base = Spork.create(:some_value => 5, :template => template)
|
55
|
+
|
56
|
+
base.some_value.should eq(10)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "returns the child's property if the template's doesn't exist" do
|
60
|
+
template = Spork.create(:some_value => nil)
|
61
|
+
base = Spork.create(:some_value => 5, :template => template)
|
62
|
+
|
63
|
+
base.some_value.should eq(5)
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should not overwrite the template's property" do
|
67
|
+
template = Spork.create(:some_value => 10)
|
68
|
+
base = Spork.create(:some_value => 5, :template => template)
|
69
|
+
|
70
|
+
base.some_value = 12
|
71
|
+
|
72
|
+
base.some_value.should eq(10)
|
73
|
+
|
74
|
+
template.some_value = nil
|
75
|
+
|
76
|
+
base.some_value.should eq(12)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should not update the local copy whenever the attribute is read' do
|
80
|
+
|
81
|
+
template = Spork.create(:some_value => 123)
|
82
|
+
base = Spork.create(:some_value => 5, :template => template)
|
83
|
+
|
84
|
+
base.some_value.should eq(123)
|
85
|
+
base.template = nil
|
86
|
+
base.some_value.should eq(5)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'should allow write if the template does not have the property' do
|
90
|
+
template = Spork.create(:some_value => nil)
|
91
|
+
base = Spork.create(:some_value => 5, :template => template)
|
92
|
+
|
93
|
+
base.some_value.should eq(5)
|
94
|
+
base.some_value = 12
|
95
|
+
|
96
|
+
base.some_value.should eq(12)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'should proxy value_before_type_cast' do
|
100
|
+
template = Spork.create(:some_value => 10)
|
101
|
+
base = Spork.create(:some_value => 5, :template => template)
|
102
|
+
|
103
|
+
base.some_value_before_type_cast.should eq(10)
|
104
|
+
end
|
105
|
+
|
106
|
+
it 'the base should take precedence over the template when specified and using before type cast' do
|
107
|
+
template = Spork.create(:some_value => 10)
|
108
|
+
base = Spork.create(:some_value => 5, :template => template)
|
109
|
+
|
110
|
+
base.template_takes_precedence = false
|
111
|
+
|
112
|
+
base.some_value_before_type_cast.should eq(5)
|
113
|
+
end
|
114
|
+
end
|
data/spec/proxy_spec.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class Foo
|
4
|
+
include ProxyForTemplate
|
5
|
+
|
6
|
+
template_accessor :a
|
7
|
+
attr_accessor :b
|
8
|
+
attr_writer :template_takes_precedence
|
9
|
+
|
10
|
+
attr_accessor :template
|
11
|
+
|
12
|
+
def template_takes_precedence(method)
|
13
|
+
@template_takes_precedence
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize
|
17
|
+
@template = Bar.new('abc123')
|
18
|
+
@a = 'abc'
|
19
|
+
@b = '123'
|
20
|
+
@template_takes_precedence = true
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class Bar
|
25
|
+
attr_accessor :a
|
26
|
+
|
27
|
+
def initialize(a)
|
28
|
+
@a = a
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe ProxyForTemplate do
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
@f = Foo.new
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should still work if the template is nil" do
|
39
|
+
@f.template = nil
|
40
|
+
@f.a.should eq('abc')
|
41
|
+
@f.b.should eq('123')
|
42
|
+
end
|
43
|
+
|
44
|
+
it "returns the template's property if it exists" do
|
45
|
+
@f.a.should eq('abc123')
|
46
|
+
end
|
47
|
+
|
48
|
+
it "returns the child's property if the templates doesn't exist" do
|
49
|
+
@f.b.should eq('123')
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should not overwrite the template's property" do
|
53
|
+
@f.a = 'arg'
|
54
|
+
@f.a.should eq('abc123')
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should allow write if the template does not have the property' do
|
58
|
+
@f.b = 'arg'
|
59
|
+
@f.b.should eq('arg')
|
60
|
+
end
|
61
|
+
|
62
|
+
it 'should use the base value if the templates is blank' do
|
63
|
+
@f.template.a = nil
|
64
|
+
@f.a.should eq('abc')
|
65
|
+
|
66
|
+
@f.template.a = ''
|
67
|
+
@f.a.should eq('abc')
|
68
|
+
end
|
69
|
+
|
70
|
+
it 'Templated class should list its templated methods' do
|
71
|
+
@f.class.templated_methods.to_a.should eq([:a])
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'templated object should list its templated methods' do
|
75
|
+
@f.templated_methods.to_a.should eq([:a])
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should tell you which methods are templated' do
|
79
|
+
@f.templated?(:a).should eq(true)
|
80
|
+
@f.templated?(:b).should eq(false)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'should update the local copy whenever the attribute is read' do
|
84
|
+
@f.a.should eq('abc123')
|
85
|
+
@f.template = nil
|
86
|
+
@f.a.should eq('abc')
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should be able to control whether proxying is turned off or on" do
|
90
|
+
@f.template_takes_precedence(:a).should eq(true)
|
91
|
+
@f.template_takes_precedence = false
|
92
|
+
@f.template_takes_precedence(:a).should eq(false)
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'the template should not take precedence if its marked as a theme' do
|
96
|
+
@f.template_takes_precedence = false
|
97
|
+
|
98
|
+
@f.template_takes_precedence(:a).should eq(false)
|
99
|
+
|
100
|
+
@f.a = 123
|
101
|
+
@f.a.should eq(123)
|
102
|
+
end
|
103
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,149 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: proxy_for_template
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Mike Emery
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-01-11 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rspec
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :development
|
33
|
+
version_requirements: *id001
|
34
|
+
- !ruby/object:Gem::Dependency
|
35
|
+
name: activerecord
|
36
|
+
prerelease: false
|
37
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
38
|
+
none: false
|
39
|
+
requirements:
|
40
|
+
- - ~>
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
hash: 23
|
43
|
+
segments:
|
44
|
+
- 2
|
45
|
+
- 3
|
46
|
+
- 10
|
47
|
+
version: 2.3.10
|
48
|
+
type: :development
|
49
|
+
version_requirements: *id002
|
50
|
+
- !ruby/object:Gem::Dependency
|
51
|
+
name: actionpack
|
52
|
+
prerelease: false
|
53
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
54
|
+
none: false
|
55
|
+
requirements:
|
56
|
+
- - ~>
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
hash: 23
|
59
|
+
segments:
|
60
|
+
- 2
|
61
|
+
- 3
|
62
|
+
- 10
|
63
|
+
version: 2.3.10
|
64
|
+
type: :development
|
65
|
+
version_requirements: *id003
|
66
|
+
- !ruby/object:Gem::Dependency
|
67
|
+
name: sqlite3
|
68
|
+
prerelease: false
|
69
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
hash: 3
|
75
|
+
segments:
|
76
|
+
- 0
|
77
|
+
version: "0"
|
78
|
+
type: :development
|
79
|
+
version_requirements: *id004
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: database_cleaner
|
82
|
+
prerelease: false
|
83
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
84
|
+
none: false
|
85
|
+
requirements:
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
hash: 3
|
89
|
+
segments:
|
90
|
+
- 0
|
91
|
+
version: "0"
|
92
|
+
type: :development
|
93
|
+
version_requirements: *id005
|
94
|
+
description: Allows method calls to be delegated to a template object.
|
95
|
+
email:
|
96
|
+
- philodoxx@gmail.com
|
97
|
+
executables: []
|
98
|
+
|
99
|
+
extensions: []
|
100
|
+
|
101
|
+
extra_rdoc_files: []
|
102
|
+
|
103
|
+
files:
|
104
|
+
- .gitignore
|
105
|
+
- Gemfile
|
106
|
+
- Rakefile
|
107
|
+
- lib/proxy_for_template.rb
|
108
|
+
- lib/proxy_for_template/version.rb
|
109
|
+
- proxy_for_template.gemspec
|
110
|
+
- spec/activerecord_spec.rb
|
111
|
+
- spec/proxy_spec.rb
|
112
|
+
- spec/spec_helper.rb
|
113
|
+
homepage: ""
|
114
|
+
licenses: []
|
115
|
+
|
116
|
+
post_install_message:
|
117
|
+
rdoc_options: []
|
118
|
+
|
119
|
+
require_paths:
|
120
|
+
- lib
|
121
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
hash: 3
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ">="
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
hash: 3
|
136
|
+
segments:
|
137
|
+
- 0
|
138
|
+
version: "0"
|
139
|
+
requirements: []
|
140
|
+
|
141
|
+
rubyforge_project: proxy_for_template
|
142
|
+
rubygems_version: 1.8.10
|
143
|
+
signing_key:
|
144
|
+
specification_version: 3
|
145
|
+
summary: Allows method calls to be delegated to a template object.
|
146
|
+
test_files:
|
147
|
+
- spec/activerecord_spec.rb
|
148
|
+
- spec/proxy_spec.rb
|
149
|
+
- spec/spec_helper.rb
|