soft_attributes 0.0.2
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 +53 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +62 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +55 -0
- data/Rakefile +6 -0
- data/db/.gitkeep +0 -0
- data/init.rb +1 -0
- data/lib/soft_attributes.rb +6 -0
- data/lib/soft_attributes/base.rb +85 -0
- data/lib/soft_attributes/noop_setter.rb +21 -0
- data/lib/soft_attributes/serialization.rb +28 -0
- data/lib/soft_attributes/version.rb +3 -0
- data/soft_attributes.gemspec +39 -0
- data/spec/soft_attributes/base_spec.rb +123 -0
- data/spec/soft_attributes/noop_setter_spec.rb +25 -0
- data/spec/soft_attributes/serialization_spec.rb +57 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +49 -0
- metadata +171 -0
data/.gitignore
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
.rvmrc
|
2
|
+
*.gem
|
3
|
+
db/*.sqlite3
|
4
|
+
|
5
|
+
# rcov generated
|
6
|
+
coverage
|
7
|
+
|
8
|
+
# rdoc generated
|
9
|
+
rdoc
|
10
|
+
|
11
|
+
# yard generated
|
12
|
+
doc
|
13
|
+
.yardoc
|
14
|
+
|
15
|
+
# bundler
|
16
|
+
.bundle
|
17
|
+
|
18
|
+
# jeweler generated
|
19
|
+
pkg
|
20
|
+
|
21
|
+
# Have editor/IDE/OS specific files you need to ignore? Consider using a global gitignore:
|
22
|
+
#
|
23
|
+
# * Create a file at ~/.gitignore
|
24
|
+
# * Include files you want ignored
|
25
|
+
# * Run: git config --global core.excludesfile ~/.gitignore
|
26
|
+
#
|
27
|
+
# After doing this, these files will be ignored in all your git projects,
|
28
|
+
# saving you from having to 'pollute' every project you touch with them
|
29
|
+
#
|
30
|
+
# Not sure what to needs to be ignored for particular editors/OSes? Here's some ideas to get you started. (Remember, remove the leading # of the line)
|
31
|
+
#
|
32
|
+
# For MacOS:
|
33
|
+
#
|
34
|
+
#.DS_Store
|
35
|
+
|
36
|
+
# For TextMate
|
37
|
+
#*.tmproj
|
38
|
+
#tmtags
|
39
|
+
|
40
|
+
# For emacs:
|
41
|
+
#*~
|
42
|
+
#\#*
|
43
|
+
#.\#*
|
44
|
+
|
45
|
+
# For vim:
|
46
|
+
#*.swp
|
47
|
+
|
48
|
+
# For redcar:
|
49
|
+
#.redcar
|
50
|
+
|
51
|
+
# For rubinius:
|
52
|
+
#*.rbc
|
53
|
+
.rvmrc
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,62 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
soft_attributes (0.0.1)
|
5
|
+
activerecord (>= 2.1.0, < 3.1.0)
|
6
|
+
activeresource (>= 2.1.0, < 3.1.0)
|
7
|
+
activesupport (>= 2.1.0, < 3.1.0)
|
8
|
+
|
9
|
+
GEM
|
10
|
+
remote: http://rubygems.org/
|
11
|
+
specs:
|
12
|
+
activemodel (3.0.10)
|
13
|
+
activesupport (= 3.0.10)
|
14
|
+
builder (~> 2.1.2)
|
15
|
+
i18n (~> 0.5.0)
|
16
|
+
activerecord (3.0.10)
|
17
|
+
activemodel (= 3.0.10)
|
18
|
+
activesupport (= 3.0.10)
|
19
|
+
arel (~> 2.0.10)
|
20
|
+
tzinfo (~> 0.3.23)
|
21
|
+
activeresource (3.0.10)
|
22
|
+
activemodel (= 3.0.10)
|
23
|
+
activesupport (= 3.0.10)
|
24
|
+
activesupport (3.0.10)
|
25
|
+
arel (2.0.10)
|
26
|
+
builder (2.1.2)
|
27
|
+
diff-lcs (1.1.3)
|
28
|
+
i18n (0.5.0)
|
29
|
+
metaclass (0.0.1)
|
30
|
+
mocha (0.10.0)
|
31
|
+
metaclass (~> 0.0.1)
|
32
|
+
nokogiri (1.5.0)
|
33
|
+
rack (1.2.3)
|
34
|
+
rack-test (0.5.7)
|
35
|
+
rack (>= 1.0)
|
36
|
+
rspec (2.6.0)
|
37
|
+
rspec-core (~> 2.6.0)
|
38
|
+
rspec-expectations (~> 2.6.0)
|
39
|
+
rspec-mocks (~> 2.6.0)
|
40
|
+
rspec-core (2.6.4)
|
41
|
+
rspec-expectations (2.6.0)
|
42
|
+
diff-lcs (~> 1.1.2)
|
43
|
+
rspec-mocks (2.6.0)
|
44
|
+
sqlite3 (1.3.4)
|
45
|
+
sqlite3-ruby (1.3.3)
|
46
|
+
sqlite3 (>= 1.3.3)
|
47
|
+
tzinfo (0.3.29)
|
48
|
+
webrat (0.7.3)
|
49
|
+
nokogiri (>= 1.2.0)
|
50
|
+
rack (>= 1.0)
|
51
|
+
rack-test (>= 0.5.3)
|
52
|
+
|
53
|
+
PLATFORMS
|
54
|
+
ruby
|
55
|
+
|
56
|
+
DEPENDENCIES
|
57
|
+
mocha
|
58
|
+
nokogiri
|
59
|
+
rspec (~> 2.6.0)
|
60
|
+
soft_attributes!
|
61
|
+
sqlite3-ruby (~> 1.3.3)
|
62
|
+
webrat
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Vijay Aravamudhan
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
= SoftAttributes
|
2
|
+
|
3
|
+
Calculated fields are usually not stored in the database. But, in many cases, you would want to
|
4
|
+
treat them just like attributes - serializing them into the xml/json representation, discarding them
|
5
|
+
if they appear on the incoming xml/json payloads, lazily initializing them (in case you are loading
|
6
|
+
them from an expensive ActiveResource call), etc. You will also want to access them by either methods
|
7
|
+
or [] notation.
|
8
|
+
|
9
|
+
== GOALS
|
10
|
+
|
11
|
+
The major distinguishing features of SoftAttributes are:
|
12
|
+
|
13
|
+
* To not pollute the attributes hash by putting non-persisted variables in them.
|
14
|
+
* But at the same time, to maintain a list of attributes that can get accessed.
|
15
|
+
* These attributes could be lazily loaded (and cached in the instance, once they
|
16
|
+
are retrieved - to avoid multiple ActiveResource calls)
|
17
|
+
* To provide an easy way to inject them into the xml/json payload as needed.
|
18
|
+
|
19
|
+
== EXAMPLE
|
20
|
+
|
21
|
+
class Foo
|
22
|
+
#will define a setter method that ignores the param
|
23
|
+
noop_setter :bar
|
24
|
+
end
|
25
|
+
|
26
|
+
== API DOCUMENTATION
|
27
|
+
|
28
|
+
== CONTRIBUTORS
|
29
|
+
|
30
|
+
* {Vijay Aravamudhan}[http://github.com/vraravam]
|
31
|
+
|
32
|
+
== LICENSE
|
33
|
+
|
34
|
+
(The MIT License)
|
35
|
+
|
36
|
+
Copyright (c) 2010 Vijay Aravamudhan
|
37
|
+
|
38
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
39
|
+
a copy of this software and associated documentation files (the
|
40
|
+
'Software'), to deal in the Software without restriction, including
|
41
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
42
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
43
|
+
permit persons to whom the Software is furnished to do so, subject to
|
44
|
+
the following conditions:
|
45
|
+
|
46
|
+
The above copyright notice and this permission notice shall be
|
47
|
+
included in all copies or substantial portions of the Software.
|
48
|
+
|
49
|
+
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
50
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
51
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
52
|
+
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
53
|
+
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
54
|
+
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
55
|
+
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/db/.gitkeep
ADDED
File without changes
|
data/init.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'soft_attributes'
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module SoftAttributes
|
2
|
+
module Base
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
def to_xml_with_soft_attributes(opts={})
|
6
|
+
attributes_to_include = self.soft_attributes.clone.with_indifferent_access.collect do |k, v|
|
7
|
+
include_in_xml = v[:include_in_xml]
|
8
|
+
if include_in_xml.present?
|
9
|
+
k if (include_in_xml.is_a?(Proc) ? include_in_xml.call(self) : include_in_xml == true)
|
10
|
+
end
|
11
|
+
end.compact
|
12
|
+
to_xml_without_soft_attributes(opts) do |xml|
|
13
|
+
attributes_to_include.each do |attr|
|
14
|
+
xml.tag!(attr, self.send(attr))
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
alias_method_chain :to_xml, :soft_attributes
|
19
|
+
|
20
|
+
# TODO: Should we support to_json here?
|
21
|
+
|
22
|
+
extend SoftAttributes::Base::ClassMethods
|
23
|
+
include SoftAttributes::Base::InstanceMethods
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
module ClassMethods
|
28
|
+
def soft_attribute(*args)
|
29
|
+
options = args.extract_options!
|
30
|
+
attr = args.first
|
31
|
+
options.assert_valid_keys(:include_in_xml, :value)
|
32
|
+
|
33
|
+
__send__(:noop_setter, attr)
|
34
|
+
soft_attributes[attr.to_s] = options.slice(:include_in_xml, :value)
|
35
|
+
end
|
36
|
+
|
37
|
+
def soft_attributes
|
38
|
+
read_inheritable_attribute(:soft_attributes) || write_inheritable_hash(:soft_attributes, {})
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module InstanceMethods
|
43
|
+
def soft_attributes
|
44
|
+
@soft_attributes ||= self.class.soft_attributes.clone
|
45
|
+
@soft_attributes.stringify_keys!
|
46
|
+
@soft_attributes
|
47
|
+
end
|
48
|
+
|
49
|
+
def soft_attributes=(new_value)
|
50
|
+
soft_attributes.merge!(new_value)
|
51
|
+
soft_attributes # return the merged hash
|
52
|
+
end
|
53
|
+
|
54
|
+
def respond_to?(method_symbol, include_private = false) #:nodoc:
|
55
|
+
attr_name = extract_attr_name_without_equals(method_symbol)
|
56
|
+
self.soft_attributes.has_key?(attr_name) || super
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
def method_missing(method_symbol, *parameters) #:nodoc:
|
61
|
+
if respond_to?(method_symbol) && !method_symbol.to_s.end_with?("=") #getter
|
62
|
+
attr_name = extract_attr_name_without_equals(method_symbol)
|
63
|
+
if self.soft_attributes.has_key?(attr_name)
|
64
|
+
value = self.soft_attributes[attr_name][:value]
|
65
|
+
return value.is_a?(Proc) ? value.call(self) : value
|
66
|
+
end
|
67
|
+
end
|
68
|
+
super
|
69
|
+
end
|
70
|
+
|
71
|
+
def extract_attr_name_without_equals(method_symbol) #:nodoc:
|
72
|
+
str = method_symbol.to_s
|
73
|
+
attr_name = str.end_with?("=") ? str.chop : str
|
74
|
+
attr_name.slice!(0) if attr_name.start_with?("_") # Rails 3 compatibility
|
75
|
+
attr_name
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
# TODO: maybe we could send this on ActiveModel?
|
82
|
+
require 'active_record'
|
83
|
+
require 'active_resource'
|
84
|
+
ActiveRecord::Base.send(:include, SoftAttributes::Base)
|
85
|
+
ActiveResource::Base.send(:include, SoftAttributes::Base)
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module SoftAttributes
|
2
|
+
module NoopSetter
|
3
|
+
def self.included(mod)
|
4
|
+
mod.module_eval do
|
5
|
+
class << self
|
6
|
+
def noop_setter(*attrs)
|
7
|
+
attrs.flatten.each do |attr|
|
8
|
+
send(:define_method, "#{attr}=") {|ignore|}
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# TODO: maybe we could send this on ActiveSupport
|
18
|
+
require 'active_record'
|
19
|
+
require 'active_resource'
|
20
|
+
ActiveRecord::Base.send(:include, SoftAttributes::NoopSetter)
|
21
|
+
ActiveResource::Base.send(:include, SoftAttributes::NoopSetter)
|
@@ -0,0 +1,28 @@
|
|
1
|
+
module SoftAttributes
|
2
|
+
module Serialization
|
3
|
+
def self.included(base)
|
4
|
+
base.class_eval do
|
5
|
+
def serializable_hash_with_soft_attributes(opts={}) #:nodoc:
|
6
|
+
attributes_to_include = self.soft_attributes.clone.with_indifferent_access.collect do |k, v|
|
7
|
+
include_in_xml = v[:include_in_xml]
|
8
|
+
if include_in_xml.present?
|
9
|
+
k if (include_in_xml.is_a?(Proc) ? include_in_xml.call(self) : include_in_xml == true)
|
10
|
+
end
|
11
|
+
end.compact
|
12
|
+
hash = attributes_to_include.inject({}) do |hash, attr|
|
13
|
+
hash[attr] = self.send(attr)
|
14
|
+
hash
|
15
|
+
end
|
16
|
+
serializable_hash_without_soft_attributes.merge(hash)
|
17
|
+
end
|
18
|
+
alias_method_chain :serializable_hash, :soft_attributes
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
if defined?(Rails) && Rails::VERSION::MAJOR >= 3
|
25
|
+
require 'active_model/serialization'
|
26
|
+
|
27
|
+
ActiveModel::Serialization.send(:include, SoftAttributes::Serialization)
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "soft_attributes/version"
|
4
|
+
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = 'soft_attributes'
|
8
|
+
s.summary = 'A library for ensuring that calculated attributes are initialized lazily and serialized/de-serialized correctly.'
|
9
|
+
s.version = SoftAttributes::VERSION
|
10
|
+
s.platform = Gem::Platform::RUBY
|
11
|
+
s.description = <<-EOS
|
12
|
+
SoftAttributes provides a consistent way to define "soft" attributes on ActiveSupport.
|
13
|
+
Typically calculated (non-persisted) attributes would be termed soft attributes.
|
14
|
+
These will be included in the xml/json payload for serialization, but will need to be discarded
|
15
|
+
if they appear in the incoming request.
|
16
|
+
EOS
|
17
|
+
|
18
|
+
s.authors = ['Vijay Aravamudhan']
|
19
|
+
s.email = ['avijayr@gmail.com']
|
20
|
+
s.homepage = 'http://github.com/vraravam/soft_attributes'
|
21
|
+
s.rubyforge_project = "soft_attributes"
|
22
|
+
s.has_rdoc = true
|
23
|
+
|
24
|
+
s.files = `git ls-files`.split("\n")
|
25
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
26
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
27
|
+
s.require_paths = ["lib"]
|
28
|
+
|
29
|
+
s.add_runtime_dependency 'activesupport', '>= 2.1.0', '< 3.1.0'
|
30
|
+
s.add_runtime_dependency 'activerecord', '>= 2.1.0', '< 3.1.0'
|
31
|
+
s.add_runtime_dependency 'activeresource', '>= 2.1.0', '< 3.1.0'
|
32
|
+
|
33
|
+
s.add_development_dependency 'sqlite3-ruby', '~> 1.3.3'
|
34
|
+
s.add_development_dependency 'rspec', '~>2.6.0'
|
35
|
+
# s.add_development_dependency 'rspec-rails', '~>2.6.0'
|
36
|
+
s.add_development_dependency 'mocha'
|
37
|
+
s.add_development_dependency 'webrat'
|
38
|
+
s.add_development_dependency 'nokogiri'
|
39
|
+
end
|
@@ -0,0 +1,123 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
class Foo < ActiveRecord::Base
|
4
|
+
soft_attribute :vijay, :include_in_xml => Proc.new{ |r| r.application =~ /vij/i }, :value => Proc.new{ |r| "#{r.name} : #{r.application}" }
|
5
|
+
soft_attribute :sujay, :include_in_xml => Proc.new{ |r| r.application =~ /jay/i }, :value => Proc.new{ |r| "#{r.application} : #{r.name}" }
|
6
|
+
soft_attribute :mythili, :include_in_xml => false, :value => Proc.new{ |r| "blah" } # eg of non-Proc - evaluating always to false for xml
|
7
|
+
soft_attribute :aravamudhan, :include_in_xml => true, :value => Proc.new{ |r| "kannan" } # eg of non-Proc - evaluating always to true for xml
|
8
|
+
soft_attribute :rakshita, :value => "child"
|
9
|
+
|
10
|
+
def to_xml(opts={})
|
11
|
+
super(opts) do |xml|
|
12
|
+
xml.tag!(:krishna, "some other random stuff to test when blocks are present")
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class Ping < ActiveRecord::Base
|
18
|
+
soft_attribute :krishna, :value => "sis"
|
19
|
+
end
|
20
|
+
|
21
|
+
describe SoftAttributes::Base do
|
22
|
+
before(:all) do
|
23
|
+
connection = ActiveRecord::Base.connection
|
24
|
+
begin
|
25
|
+
connection.create_table(:foos) do |t|
|
26
|
+
t.string :name
|
27
|
+
t.string :application
|
28
|
+
end
|
29
|
+
|
30
|
+
connection.create_table(:pings) do |t|
|
31
|
+
t.string :name
|
32
|
+
end
|
33
|
+
rescue Exception => e
|
34
|
+
RAILS_DEFAULT_LOGGER.warn "Error in before(:each): #{e}" if defined?(RAILS_DEFAULT_LOGGER)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
after(:all) do
|
39
|
+
begin
|
40
|
+
connection = ActiveRecord::Base.connection
|
41
|
+
connection.drop_table(Foo.table_name)
|
42
|
+
connection.drop_table(Ping.table_name)
|
43
|
+
rescue Exception => e
|
44
|
+
RAILS_DEFAULT_LOGGER.warn "Error in after(:each): #{e}" if defined?(RAILS_DEFAULT_LOGGER)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should define noop setters for a single attribute" do
|
49
|
+
foo = Foo.new
|
50
|
+
foo.respond_to?("vijay=").should be_true
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should raise an error if unknown attributes are passed" do
|
54
|
+
lambda {
|
55
|
+
Foo.send(:soft_attribute, :john, :invalid_key1 => "some value 1", :invalid_key2 => "some value 2")
|
56
|
+
}.should raise_error(ArgumentError) do |e|
|
57
|
+
e.message.should match(/^Unknown key(s): /)
|
58
|
+
e.message.should include("invalid_key1")
|
59
|
+
e.message.should include("invalid_key2")
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should invoke the provided getter method" do
|
64
|
+
foo = Foo.new
|
65
|
+
foo.name = "my name"
|
66
|
+
foo.application = 'testing soft_attributes'
|
67
|
+
foo.vijay.should == "my name : testing soft_attributes"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should discard the value from the setter and re-evaluate the getter" do
|
71
|
+
foo = Foo.new
|
72
|
+
foo.name = "my name"
|
73
|
+
foo.application = 'testing soft_attributes'
|
74
|
+
foo.vijay = "discarded value"
|
75
|
+
foo.vijay.should == "my name : testing soft_attributes"
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should not need a Proc for the value" do
|
79
|
+
foo = Foo.new
|
80
|
+
foo.rakshita.should == "child"
|
81
|
+
end
|
82
|
+
|
83
|
+
it "should not pollute the attributes from one instance with another" do
|
84
|
+
f1 = Foo.new
|
85
|
+
f2 = Foo.new
|
86
|
+
f1.soft_attributes.object_id.should_not == f2.soft_attributes.object_id
|
87
|
+
f1.soft_attributes.merge!({:a => "b"})
|
88
|
+
f3 = Foo.new
|
89
|
+
f3.soft_attributes.should_not have_key(:a)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should not pollute the attributes from a different class" do
|
93
|
+
Foo.soft_attributes.should_not == Ping.soft_attributes
|
94
|
+
Foo.new.soft_attributes.should_not == Ping.new.soft_attributes
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "to_xml" do
|
98
|
+
it "should include all attributes that evaluate to true with both attributes using Procs evaluating to true" do
|
99
|
+
foo = Foo.new(:name => "rakshita", :application => "vijay's demo")
|
100
|
+
xml = foo.to_xml
|
101
|
+
xml.should have_tag("name", :content => foo.name)
|
102
|
+
xml.should have_tag("vijay", :content => "#{foo.name} : #{foo.application}")
|
103
|
+
xml.should have_tag("sujay", :content => "#{foo.application} : #{foo.name}")
|
104
|
+
xml.should_not have_tag("mythili")
|
105
|
+
xml.should have_tag("aravamudhan", :content => "kannan")
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should include all attributes (including the ones which do not use Procs)" do
|
109
|
+
foo = Foo.new(:name => "rakshita", :application => "vijay's demo")
|
110
|
+
xml = foo.to_xml
|
111
|
+
xml.should have_tag("aravamudhan", :content => "kannan")
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should never include any attributes that evaluate to false" do
|
115
|
+
foo = Foo.new(:name => "rakshita", :application => "vij's demo")
|
116
|
+
xml = foo.to_xml
|
117
|
+
xml.should have_tag("name", :content => foo.name)
|
118
|
+
xml.should have_tag("vijay", :content => "#{foo.name} : #{foo.application}")
|
119
|
+
xml.should_not have_tag("sujay")
|
120
|
+
xml.should_not have_tag("mythili")
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
class Bar
|
4
|
+
include SoftAttributes::NoopSetter
|
5
|
+
|
6
|
+
noop_setter :foo
|
7
|
+
noop_setter :bar, :baz
|
8
|
+
end
|
9
|
+
|
10
|
+
describe SoftAttributes::NoopSetter do
|
11
|
+
it "should define noop setters for a single attribute" do
|
12
|
+
["foo=", "bar=", "baz="].each do |method|
|
13
|
+
Bar.public_instance_methods.include?(method.to_sym).should be_true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should accept parameters for the generated setter methods" do
|
18
|
+
f = Bar.new
|
19
|
+
lambda {
|
20
|
+
f.foo = "qwerty"
|
21
|
+
f.bar = "asdfg"
|
22
|
+
f.baz = "zxcvb"
|
23
|
+
}.should_not raise_error
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require File.expand_path('../../spec_helper', __FILE__)
|
2
|
+
load 'soft_attributes/serialization.rb'
|
3
|
+
|
4
|
+
class Pong < ActiveRecord::Base
|
5
|
+
soft_attribute :krishna, :value => "sis"
|
6
|
+
soft_attribute :anand, :value => "bil", :include_in_xml => true
|
7
|
+
soft_attribute :dittu, :value => "nep", :include_in_xml => Proc.new{ |r| r.name.nil? }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe SoftAttributes::Serialization do
|
11
|
+
before(:all) do
|
12
|
+
require 'active_model/serialization'
|
13
|
+
|
14
|
+
ActiveModel::Serialization.send(:include, SoftAttributes::Serialization)
|
15
|
+
|
16
|
+
connection = ActiveRecord::Base.connection
|
17
|
+
begin
|
18
|
+
connection.create_table(:pongs) do |t|
|
19
|
+
t.string :name
|
20
|
+
t.string :application
|
21
|
+
end
|
22
|
+
rescue Exception => e
|
23
|
+
RAILS_DEFAULT_LOGGER.warn "Error in before(:each): #{e}" if defined?(RAILS_DEFAULT_LOGGER)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
after(:all) do
|
28
|
+
begin
|
29
|
+
connection = ActiveRecord::Base.connection
|
30
|
+
connection.drop_table(Pong.table_name)
|
31
|
+
rescue Exception => e
|
32
|
+
RAILS_DEFAULT_LOGGER.warn "Error in after(:each): #{e}" if defined?(RAILS_DEFAULT_LOGGER)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should define a method called serializable_hash_with_soft_attributes" do
|
37
|
+
Pong.new.public_methods.include?(:serializable_hash_with_soft_attributes).should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should not include a soft attribute that does not have the 'include_in_xml' key" do
|
41
|
+
record = Pong.new
|
42
|
+
record.serializable_hash.should_not have_key("krishna")
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should include a soft attribute that does have the 'include_in_xml' key with a value of true" do
|
46
|
+
record = Pong.new
|
47
|
+
record.serializable_hash.should have_key("anand")
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should include a soft attribute that does have the 'include_in_xml' key that evaluates to true from a Proc" do
|
51
|
+
record = Pong.new
|
52
|
+
record.serializable_hash.should have_key("dittu")
|
53
|
+
|
54
|
+
record = Pong.new(:name => "some non nil")
|
55
|
+
record.serializable_hash.should_not have_key("dittu")
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec.opts
ADDED
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# This file is copied to ~/spec when you run 'ruby script/generate rspec'
|
2
|
+
# from the project root directory.
|
3
|
+
ENV["RAILS_ENV"] = "test"
|
4
|
+
|
5
|
+
require 'rubygems'
|
6
|
+
require 'bundler/setup'
|
7
|
+
require 'mocha'
|
8
|
+
require "nokogiri"
|
9
|
+
require "webrat/core/matchers/have_tag"
|
10
|
+
require 'soft_attributes'
|
11
|
+
|
12
|
+
RSpec.configure do |config|
|
13
|
+
config.mock_with :mocha
|
14
|
+
config.include(Webrat::Matchers)
|
15
|
+
config.include(Webrat::HaveTagMatcher)
|
16
|
+
include Webrat::HaveTagMatcher
|
17
|
+
|
18
|
+
config.before(:all) do
|
19
|
+
`touch db/test.sqlite3`
|
20
|
+
ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :encoding => "utf8", :database => "db/test.sqlite3")
|
21
|
+
|
22
|
+
ActiveRecord::Base.connection.create_table :soft_attributes_items, :force => true do |t|
|
23
|
+
t.string :name
|
24
|
+
t.timestamps
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
config.after(:all) do
|
29
|
+
ActiveRecord::Base.connection.drop_table :soft_attributes_items
|
30
|
+
`rm -f db/test.sqlite3`
|
31
|
+
end
|
32
|
+
|
33
|
+
config.before(:each) do
|
34
|
+
class SoftAttributesItem < ActiveRecord::Base
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
config.after(:each) do
|
39
|
+
Object.send(:remove_const, :SoftAttributesItem)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def putsh(stuff)
|
44
|
+
puts "#{ERB::Util.h(stuff)}<br/>"
|
45
|
+
end
|
46
|
+
|
47
|
+
def ph(stuff)
|
48
|
+
putsh stuff.inspect
|
49
|
+
end
|
metadata
ADDED
@@ -0,0 +1,171 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soft_attributes
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.2
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Vijay Aravamudhan
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2011-09-10 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activesupport
|
16
|
+
requirement: &2165585100 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: 2.1.0
|
22
|
+
- - <
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: 3.1.0
|
25
|
+
type: :runtime
|
26
|
+
prerelease: false
|
27
|
+
version_requirements: *2165585100
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: activerecord
|
30
|
+
requirement: &2165584100 !ruby/object:Gem::Requirement
|
31
|
+
none: false
|
32
|
+
requirements:
|
33
|
+
- - ! '>='
|
34
|
+
- !ruby/object:Gem::Version
|
35
|
+
version: 2.1.0
|
36
|
+
- - <
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 3.1.0
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: *2165584100
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: activeresource
|
44
|
+
requirement: &2165580340 !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: 2.1.0
|
50
|
+
- - <
|
51
|
+
- !ruby/object:Gem::Version
|
52
|
+
version: 3.1.0
|
53
|
+
type: :runtime
|
54
|
+
prerelease: false
|
55
|
+
version_requirements: *2165580340
|
56
|
+
- !ruby/object:Gem::Dependency
|
57
|
+
name: sqlite3-ruby
|
58
|
+
requirement: &2165579460 !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ~>
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: 1.3.3
|
64
|
+
type: :development
|
65
|
+
prerelease: false
|
66
|
+
version_requirements: *2165579460
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: rspec
|
69
|
+
requirement: &2165578900 !ruby/object:Gem::Requirement
|
70
|
+
none: false
|
71
|
+
requirements:
|
72
|
+
- - ~>
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 2.6.0
|
75
|
+
type: :development
|
76
|
+
prerelease: false
|
77
|
+
version_requirements: *2165578900
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: mocha
|
80
|
+
requirement: &2165578300 !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: *2165578300
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: webrat
|
91
|
+
requirement: &2165577320 !ruby/object:Gem::Requirement
|
92
|
+
none: false
|
93
|
+
requirements:
|
94
|
+
- - ! '>='
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
type: :development
|
98
|
+
prerelease: false
|
99
|
+
version_requirements: *2165577320
|
100
|
+
- !ruby/object:Gem::Dependency
|
101
|
+
name: nokogiri
|
102
|
+
requirement: &2165576900 !ruby/object:Gem::Requirement
|
103
|
+
none: false
|
104
|
+
requirements:
|
105
|
+
- - ! '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
type: :development
|
109
|
+
prerelease: false
|
110
|
+
version_requirements: *2165576900
|
111
|
+
description: ! " SoftAttributes provides a consistent way to define \"soft\" attributes
|
112
|
+
on ActiveSupport.\n Typically calculated (non-persisted) attributes would be
|
113
|
+
termed soft attributes.\n These will be included in the xml/json payload for
|
114
|
+
serialization, but will need to be discarded\n if they appear in the incoming
|
115
|
+
request.\n"
|
116
|
+
email:
|
117
|
+
- avijayr@gmail.com
|
118
|
+
executables: []
|
119
|
+
extensions: []
|
120
|
+
extra_rdoc_files: []
|
121
|
+
files:
|
122
|
+
- .gitignore
|
123
|
+
- Gemfile
|
124
|
+
- Gemfile.lock
|
125
|
+
- MIT-LICENSE
|
126
|
+
- README.rdoc
|
127
|
+
- Rakefile
|
128
|
+
- db/.gitkeep
|
129
|
+
- init.rb
|
130
|
+
- lib/soft_attributes.rb
|
131
|
+
- lib/soft_attributes/base.rb
|
132
|
+
- lib/soft_attributes/noop_setter.rb
|
133
|
+
- lib/soft_attributes/serialization.rb
|
134
|
+
- lib/soft_attributes/version.rb
|
135
|
+
- soft_attributes.gemspec
|
136
|
+
- spec/soft_attributes/base_spec.rb
|
137
|
+
- spec/soft_attributes/noop_setter_spec.rb
|
138
|
+
- spec/soft_attributes/serialization_spec.rb
|
139
|
+
- spec/spec.opts
|
140
|
+
- spec/spec_helper.rb
|
141
|
+
homepage: http://github.com/vraravam/soft_attributes
|
142
|
+
licenses: []
|
143
|
+
post_install_message:
|
144
|
+
rdoc_options: []
|
145
|
+
require_paths:
|
146
|
+
- lib
|
147
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
148
|
+
none: false
|
149
|
+
requirements:
|
150
|
+
- - ! '>='
|
151
|
+
- !ruby/object:Gem::Version
|
152
|
+
version: '0'
|
153
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
154
|
+
none: false
|
155
|
+
requirements:
|
156
|
+
- - ! '>='
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
requirements: []
|
160
|
+
rubyforge_project: soft_attributes
|
161
|
+
rubygems_version: 1.8.10
|
162
|
+
signing_key:
|
163
|
+
specification_version: 3
|
164
|
+
summary: A library for ensuring that calculated attributes are initialized lazily
|
165
|
+
and serialized/de-serialized correctly.
|
166
|
+
test_files:
|
167
|
+
- spec/soft_attributes/base_spec.rb
|
168
|
+
- spec/soft_attributes/noop_setter_spec.rb
|
169
|
+
- spec/soft_attributes/serialization_spec.rb
|
170
|
+
- spec/spec.opts
|
171
|
+
- spec/spec_helper.rb
|