hattr_accessor 1.1.0

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.
@@ -0,0 +1,31 @@
1
+ 2009-03-05 - Sean Huber (shuber@huberry.com)
2
+ * Merge pixeltrix/master
3
+ * Include Huberry::HattrAccessor in Object instead of Class
4
+ * Update README
5
+ * Update gemspec
6
+
7
+ 2009-01-18 - Sean Huber (shuber@huberry.com)
8
+ * Boolean type casted empty strings should return false
9
+
10
+ 2009-01-12 - Sean Huber (shuber@huberry.com)
11
+ * Check for existing reader and writer methods separately before creating default ones for options[:attribute]
12
+ * Remove alias_method_chain - unnecessary
13
+
14
+ 2009-01-10 - Sean Huber (shuber@huberry.com)
15
+ * Object includes Huberry::AliasMethodChain instead of Module
16
+ * Remove init.rb
17
+
18
+ 2009-01-08 - Sean Huber (shuber@huberry.com)
19
+ * Update CHANGELOG email addresses
20
+ * Remove .gitignore
21
+ * Update README
22
+ * Move include logic into the main hattr_accessor file
23
+
24
+ 2008-10-17 - Sean Huber (shuber@huberry.com)
25
+ * Refactor #{attribute}_with_hattr_accessor method
26
+ * Rename doc/README.markdown to doc/README
27
+
28
+ 2008-10-14 - Sean Huber (shuber@huberry.com)
29
+ * Initial import
30
+ * Update README
31
+ * Add tests to ensure errors are raised when :attribute does not exist
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2008 Sean Huber (shuber@huberry.com)
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.
@@ -0,0 +1,115 @@
1
+ hattr\_accessor
2
+ ===============
3
+
4
+ Allows you to define attr\_accessors that reference members of a hash
5
+
6
+
7
+ Installation
8
+ ------------
9
+
10
+ gem install shuber-hattr_accessor --source http://gems.github.com
11
+
12
+
13
+ Usage
14
+ -----
15
+
16
+ The hattr\_accessor method requires an option named `:attribute` which should be name of an attribute which will store the hash. For example:
17
+
18
+ class DataSource
19
+ hattr_accessor :adapter, :username, :password, :attribute => :credentials
20
+ end
21
+
22
+ The reader and writer methods for `:attribute` (`:credentials` in the example above) would be automatically created unless they exist already.
23
+ You can then use those attributes like normal ones:
24
+
25
+ @data_source = DataSource.new
26
+ @data_source.adapter = 'mysql'
27
+ @data_source.username = 'root'
28
+ @data_source.credentials # { :adapter => 'mysql', :username => 'root' }
29
+
30
+ @data_source.credentials = {}
31
+ @data_source.adapter # nil
32
+
33
+ The reader method for `:attribute` is overwritten with logic to ensure that it returns a hash by default.
34
+
35
+ @data_source = DataSource.new
36
+ @data_source.credentials # {}
37
+
38
+ You may optionally pass a `:type` option which will type cast the values when calling their getter methods. This is useful if you're using this
39
+ gem with rails which will pass values as strings if submitted from a form. For example:
40
+
41
+ class CustomField::Date < CustomField
42
+ hattr_accessor :offset, :type => :integer, :attribute => :configuration
43
+ hattr_accessor :unit, :reference, :type => :string, :attribute => :configuration
44
+
45
+ def default_value
46
+ self.offset.send(self.unit.to_sym).send(self.reference.to_sym)
47
+ end
48
+ end
49
+
50
+ @custom_field = CustomField::Date.new(:offset => '5', :unit => 'days', :reference => 'from_now')
51
+ @custom_field.offset # 5 (notice it's an integer, not a string)
52
+ @custom_field.default_value # evaluates 5.days.from_now
53
+
54
+ The current options (email me for suggestions for others) for `:type` are:
55
+
56
+ :string
57
+ :integer
58
+ :float
59
+ :boolean
60
+ :decimal
61
+ :array
62
+
63
+ To specify a default value for a member use the `:default` option. For example:
64
+
65
+ class DataSource
66
+ hattr_accessor :adapter, :default => 'mysql', :attribute => :credentials
67
+ hattr_accessor :username, :default => 'root', :attribute => :credentials
68
+ hattr_accessor :password, :attribute => :credentials
69
+ end
70
+
71
+ @data_source = DataSource.new
72
+ @data_source.adapter # 'mysql'
73
+
74
+ You can also specify a proc for the default value. For example:
75
+
76
+ class DataSource
77
+ hattr_accessor :adapter, :default => 'mysql', :attribute => :credentials
78
+ hattr_accessor :username, :attribute => :credentials,
79
+ :default => lambda { |datasource| Etc.getpwuid(Process.uid).name }
80
+ hattr_accessor :password, :attribute => :credentials
81
+ end
82
+
83
+ @data_source = DataSource.new
84
+ @data_source.username # 'process_username'
85
+
86
+ If you want to take advantage of type casting but also want to return `nil` if a value has not been set then use the `:allow_nil` option.
87
+ By default `:allow_nil` is false for typed members but true for non-typed members. For example:
88
+
89
+ class DataSource
90
+ hattr_accessor :adapter, :type => :string, :allow_nil => true, :attribute => :credentials
91
+ hattr_accessor :username, :type => :string, :attribute => :credentials
92
+ hattr_accessor :password, :attribute => :credentials
93
+ end
94
+
95
+ @data_source = DataSource.new
96
+ @data_source.adapter # nil
97
+ @data_source.username # ''
98
+ @data_source.password # nil
99
+
100
+ NOTE: Make sure your call `define_attribute_methods` before calling `hattr_accessor` when you're using ActiveRecord and your `:attribute` is a
101
+ database field. The call to `define_attribute_methods` must be after the `serialize` call so that `define_attribute_methods` knows about the
102
+ serialized field.
103
+
104
+ class CustomField < ActiveRecord::Base
105
+ serialize :configuration, Hash
106
+ define_attribute_methods
107
+
108
+ hattr_accessor :testing, :attribute => :configuration
109
+ end
110
+
111
+
112
+ Contact
113
+ -------
114
+
115
+ Problems, comments, and suggestions all welcome: [shuber@huberry.com](mailto:shuber@huberry.com)
@@ -0,0 +1,55 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = 'hattr_accessor'
8
+ gem.summary = 'Allows you to define attr_accessors that reference members of a hash'
9
+ gem.description = 'Allows you to define attr_accessors that reference members of a hash'
10
+ gem.email = 'shuber@huberry.com'
11
+ gem.homepage = 'http://github.com/shuber/hattr_accessor'
12
+ gem.authors = ['Sean Huber']
13
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
14
+ end
15
+ rescue LoadError
16
+ puts 'Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler'
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ begin
27
+ require 'rcov/rcovtask'
28
+ Rcov::RcovTask.new do |test|
29
+ test.libs << 'test'
30
+ test.pattern = 'test/**/*_test.rb'
31
+ test.verbose = true
32
+ end
33
+ rescue LoadError
34
+ task :rcov do
35
+ abort 'RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov'
36
+ end
37
+ end
38
+
39
+ task :test => :check_dependencies
40
+
41
+ task :default => :test
42
+
43
+ require 'rake/rdoctask'
44
+ Rake::RDocTask.new do |rdoc|
45
+ if File.exist?('VERSION')
46
+ version = File.read('VERSION')
47
+ else
48
+ version = ""
49
+ end
50
+
51
+ rdoc.rdoc_dir = 'rdoc'
52
+ rdoc.title = "hattr_accessor #{version}"
53
+ rdoc.rdoc_files.include('README*')
54
+ rdoc.rdoc_files.include('lib/**/*.rb')
55
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 1.1.0
@@ -0,0 +1,51 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{hattr_accessor}
8
+ s.version = "1.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Sean Huber"]
12
+ s.date = %q{2010-01-06}
13
+ s.description = %q{Allows you to define attr_accessors that reference members of a hash}
14
+ s.email = %q{shuber@huberry.com}
15
+ s.extra_rdoc_files = [
16
+ "README.markdown"
17
+ ]
18
+ s.files = [
19
+ "CHANGELOG",
20
+ "MIT-LICENSE",
21
+ "README.markdown",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "hattr_accessor.gemspec",
25
+ "lib/hattr_accessor.rb",
26
+ "test/active_record_test.rb",
27
+ "test/fixtures/manufacturers.yml",
28
+ "test/fixtures/products.yml",
29
+ "test/hattr_accessor_test.rb"
30
+ ]
31
+ s.homepage = %q{http://github.com/shuber/hattr_accessor}
32
+ s.rdoc_options = ["--charset=UTF-8"]
33
+ s.require_paths = ["lib"]
34
+ s.rubygems_version = %q{1.3.5}
35
+ s.summary = %q{Allows you to define attr_accessors that reference members of a hash}
36
+ s.test_files = [
37
+ "test/active_record_test.rb",
38
+ "test/hattr_accessor_test.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
+ else
47
+ end
48
+ else
49
+ end
50
+ end
51
+
@@ -0,0 +1,115 @@
1
+ require 'bigdecimal'
2
+
3
+ module Huberry
4
+ module HattrAccessor
5
+ class MissingAttributeError < StandardError; self; end
6
+
7
+ def hattr_defined?(attribute)
8
+ hattr_attributes.include?(attribute.to_sym)
9
+ end
10
+
11
+ def hattr_attributes
12
+ @hattr_attributes ||= []
13
+ end
14
+
15
+ def hattr_accessor(*attrs)
16
+ options = attrs.last.is_a?(Hash) ? attrs.pop : {}
17
+
18
+ raise MissingAttributeError, 'Must specify the :attribute option with the name of an attribute which will store the hash' if options[:attribute].nil?
19
+
20
+ attrs.each do |name|
21
+ hattr_attributes << name
22
+
23
+ # Defines a type casting getter method for each attribute
24
+ #
25
+ define_method name do
26
+ value = send("#{name}_before_type_cast".to_sym)
27
+ return value if options[:allow_nil] && value.nil?
28
+ case options[:type]
29
+ when :string
30
+ value.to_s
31
+ when :symbol
32
+ value.to_s.to_sym
33
+ when :integer
34
+ value.to_i
35
+ when :float
36
+ value.to_f
37
+ when :boolean
38
+ ![false, nil, 0, '0', ''].include?(value)
39
+ when :decimal
40
+ BigDecimal.new(value.to_s)
41
+ when :array
42
+ Array(value)
43
+ else
44
+ value
45
+ end
46
+ end
47
+
48
+ # Defines a predicate method for each attribute
49
+ #
50
+ define_method "#{name}?" do
51
+ send(name) ? true : false
52
+ end
53
+
54
+ # Defines a setter method for each attribute
55
+ #
56
+ define_method "#{name}=" do |value|
57
+ send(options[:attribute])[name] = value
58
+ end
59
+
60
+ # Define a *_before_type_cast method so that we can validate
61
+ #
62
+ define_method "#{name}_before_type_cast" do
63
+ send(options[:attribute]).key?(name) ? send(options[:attribute])[name] : (options[:default].respond_to?(:call) ? options[:default].call(self) : options[:default])
64
+ end
65
+ end
66
+
67
+ # Create the reader for #{options[:attribute]} unless it exists already
68
+ #
69
+ attr_reader options[:attribute] unless instance_methods.include?(options[:attribute].to_s)
70
+
71
+ # Create the writer for #{options[:attribute]} unless it exists already
72
+ #
73
+ attr_writer options[:attribute] unless instance_methods.include?("#{options[:attribute]}=")
74
+
75
+ # Overwrites the method passed as the :attribute option to ensure that it is a hash by default
76
+ #
77
+ unless instance_methods.include?("#{options[:attribute]}_with_hattr_accessor")
78
+ class_eval <<-EOF
79
+ def #{options[:attribute]}_with_hattr_accessor
80
+ self.#{options[:attribute]} = {} if #{options[:attribute]}_without_hattr_accessor.nil?
81
+ #{options[:attribute]}_without_hattr_accessor
82
+ end
83
+ alias_method :#{options[:attribute]}_without_hattr_accessor, :#{options[:attribute]}
84
+ alias_method :#{options[:attribute]}, :#{options[:attribute]}_with_hattr_accessor
85
+ EOF
86
+ end
87
+ end
88
+
89
+ module ActiveRecordExtensions
90
+ def self.included(base)
91
+ base.class_eval do
92
+
93
+ def read_attribute_with_hattr_accessor(attribute)
94
+ self.class.hattr_defined?(attribute) ? send(attribute) : read_attribute_without_hattr_accessor(attribute)
95
+ end
96
+ alias_method_chain :read_attribute, :hattr_accessor
97
+
98
+ def write_attribute_with_hattr_accessor(attribute, value)
99
+ self.class.hattr_defined?(attribute) ? send("#{attribute}=".to_sym, value) : write_attribute_without_hattr_accessor(attribute, value)
100
+ end
101
+ alias_method_chain :write_attribute, :hattr_accessor
102
+
103
+ def query_attribute_with_hattr_accessor(attribute)
104
+ self.class.hattr_defined?(attribute) ? send("#{attribute}?".to_sym) : query_attribute_without_hattr_accessor(attribute)
105
+ end
106
+ alias_method_chain :query_attribute, :hattr_accessor
107
+
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
113
+
114
+ Object.send :include, Huberry::HattrAccessor
115
+ ActiveRecord::Base.send :include, Huberry::HattrAccessor::ActiveRecordExtensions if Object.const_defined?(:ActiveRecord)
@@ -0,0 +1,98 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'active_record'
4
+ require 'active_record/fixtures'
5
+ require File.dirname(__FILE__) + '/../lib/hattr_accessor'
6
+
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :dbfile => ":memory:")
8
+
9
+ ActiveRecord::Migration.suppress_messages do
10
+ ActiveRecord::Schema.define(:version => 1) do
11
+ create_table :manufacturers do |t|
12
+ t.string :name, :limit => 30, :null => false
13
+ end
14
+
15
+ create_table :products do |t|
16
+ t.string :properties, :limit => 255, :null => false
17
+ end
18
+ end
19
+ end
20
+
21
+ class Manufacturer < ActiveRecord::Base
22
+ end
23
+
24
+ class Product < ActiveRecord::Base
25
+ serialize :properties, Hash
26
+ define_attribute_methods
27
+
28
+ hattr_accessor :name, :type => :string, :attribute => :properties
29
+ hattr_accessor :manufacturer_id, :type => :integer, :attribute => :properties, :allow_nil => true
30
+ hattr_accessor :colour, :type => :string, :attribute => :properties
31
+ hattr_accessor :weight, :type => :decimal, :attribute => :properties
32
+
33
+ belongs_to :manufacturer
34
+
35
+ validates_presence_of :name, :manufacturer_id, :colour, :weight
36
+ validates_length_of :name, :maximum => 30
37
+ validates_inclusion_of :colour, :in => %(Red Green Blue)
38
+ validates_numericality_of :weight
39
+ end
40
+
41
+ class ActiveRecordTest < Test::Unit::TestCase
42
+
43
+ def setup
44
+ Fixtures.create_fixtures(File.dirname(__FILE__) + '/fixtures', ActiveRecord::Base.connection.tables)
45
+ end
46
+
47
+ def teardown
48
+ Fixtures.reset_cache
49
+ end
50
+
51
+ def test_should_fetch_belongs_to_assocation
52
+ assert_equal Manufacturer.find(1), Product.find(1).manufacturer
53
+ end
54
+
55
+ def test_should_assign_belongs_to_assocation
56
+ product = Product.find(1)
57
+ manufacturer_1 = Manufacturer.find(1)
58
+ manufacturer_2 = Manufacturer.find(2)
59
+ assert_equal product.manufacturer, manufacturer_1
60
+ product.manufacturer = manufacturer_2
61
+ assert product.save
62
+ product.reload
63
+ assert_equal product.manufacturer, manufacturer_2
64
+ end
65
+
66
+ def test_should_pass_validations
67
+ product = Product.find(1)
68
+ manufacturer_3 = Manufacturer.find(3)
69
+ assert product.valid?
70
+ product.name = "Widget D"
71
+ product.manufacturer = manufacturer_3
72
+ product.colour = "Blue"
73
+ product.weight = 10.0
74
+ assert product.valid?
75
+ end
76
+
77
+ def test_should_fail_validations
78
+ product = Product.find(1)
79
+ assert product.valid?
80
+ product.name = "This is a very long name that needs to be over 30 characters"
81
+ assert !product.valid?
82
+ assert product.errors.on(:name).include?("too long")
83
+ product.reload
84
+ product.manufacturer_id = nil
85
+ assert !product.valid?
86
+ assert product.errors.on(:manufacturer_id).include?("can't be blank")
87
+ product.reload
88
+ product.colour = "Black"
89
+ assert !product.valid?
90
+ assert product.errors.on(:colour).include?("is not included in the list")
91
+ product.reload
92
+ product.weight = "Not a number"
93
+ assert !product.valid?
94
+ assert product.errors.on(:weight).include?("is not a number")
95
+ product.reload
96
+ end
97
+
98
+ end
@@ -0,0 +1,11 @@
1
+ acme:
2
+ id: 1
3
+ name: Acme
4
+
5
+ bodgit:
6
+ id: 2
7
+ name: Bodgit
8
+
9
+ scarper:
10
+ id: 3
11
+ name: Scarper
@@ -0,0 +1,11 @@
1
+ widget_a:
2
+ id: 1
3
+ properties: "---\n :name: \"Widget A\"\n :manufacturer_id: 1\n :colour: Red\n :weight: 1.0\n"
4
+
5
+ widget_b:
6
+ id: 2
7
+ properties: "---\n :name: \"Widget B\"\n :manufacturer_id: 2\n :colour: Green\n :weight: 2.0\n"
8
+
9
+ widget_c:
10
+ id: 3
11
+ properties: "---\n :name: \"Widget C\"\n :manufacturer_id: 3\n :colour: Blue\n :weight: 3.0\n"
@@ -0,0 +1,286 @@
1
+ require 'test/unit'
2
+ require File.dirname(__FILE__) + '/../lib/hattr_accessor'
3
+
4
+ class CustomField
5
+ hattr_accessor :name, :type => :string, :attribute => :configuration
6
+ hattr_accessor :type, :type => :symbol, :attribute => :configuration
7
+ hattr_accessor :unit, :reference, :attribute => :configuration
8
+ hattr_accessor :offset, :type => :integer, :attribute => :configuration
9
+ hattr_accessor :amount, :type => :float, :allow_nil => true, :attribute => :configuration
10
+ hattr_accessor :price, :type => :decimal, :default => '5.0', :attribute => :configuration
11
+ hattr_accessor :sale_price, :type => :decimal, :attribute => :configuration,
12
+ :default => lambda { |custom_field| custom_field.price / 2 }
13
+ hattr_accessor :required, :type => :boolean, :attribute => :configuration2
14
+ hattr_accessor :sizes, :type => :array, :attribute => :configuration
15
+
16
+ def configuration2
17
+ @configuration2 ||= { :some_default_reader_value => true }
18
+ end
19
+
20
+ def configuration2=(value)
21
+ @configuration2 = value.merge(:some_default_writer_value => true)
22
+ end
23
+ end
24
+
25
+ class HattrAccessorTest < Test::Unit::TestCase
26
+
27
+ def setup
28
+ @custom_field = CustomField.new
29
+ end
30
+
31
+ def test_should_alias_method_chain_configuration
32
+ assert CustomField.method_defined?(:configuration_with_hattr_accessor)
33
+ assert CustomField.method_defined?(:configuration_without_hattr_accessor)
34
+ end
35
+
36
+ def test_configuration_should_be_a_hash_by_default
37
+ assert_equal({}, @custom_field.configuration)
38
+ end
39
+
40
+ def test_should_set_name
41
+ @custom_field.name = 'Date'
42
+ assert_equal({ :name => 'Date' }, @custom_field.configuration)
43
+ end
44
+
45
+ def test_should_get_name
46
+ @custom_field.name = 'Date'
47
+ assert_equal 'Date', @custom_field.name
48
+ end
49
+
50
+ def test_should_get_name_predicate
51
+ @custom_field.name = 'Date'
52
+ assert_equal true, @custom_field.name?
53
+ end
54
+
55
+ def test_should_type_cast_name_as_string
56
+ assert_equal '', @custom_field.name
57
+ end
58
+
59
+ def test_should_set_type
60
+ @custom_field.type = :date
61
+ assert_equal({ :type => :date }, @custom_field.configuration)
62
+ end
63
+
64
+ def test_should_get_type
65
+ @custom_field.type = :date
66
+ assert_equal :date, @custom_field.type
67
+ end
68
+
69
+ def test_should_get_type_predicate
70
+ @custom_field.type = :date
71
+ assert_equal true, @custom_field.type?
72
+ end
73
+
74
+ def test_should_type_cast_type_as_symbol
75
+ @custom_field.type = 'date'
76
+ assert_equal :date, @custom_field.type
77
+ end
78
+
79
+ def test_should_set_unit
80
+ @custom_field.unit = 'days'
81
+ assert_equal({ :unit => 'days' }, @custom_field.configuration)
82
+ end
83
+
84
+ def test_should_get_unit
85
+ @custom_field.unit = 'days'
86
+ assert_equal 'days', @custom_field.unit
87
+ end
88
+
89
+ def test_should_get_unit_predicate
90
+ @custom_field.unit = 'days'
91
+ assert_equal true, @custom_field.unit?
92
+ end
93
+
94
+ def test_should_set_reference
95
+ @custom_field.reference = 'from_now'
96
+ assert_equal({ :reference => 'from_now' }, @custom_field.configuration)
97
+ end
98
+
99
+ def test_should_get_reference
100
+ @custom_field.reference = 'from_now'
101
+ assert_equal 'from_now', @custom_field.reference
102
+ end
103
+
104
+ def test_should_get_reference_predicate
105
+ @custom_field.reference = 'from_now'
106
+ assert_equal true, @custom_field.reference?
107
+ end
108
+
109
+ def test_should_set_offset
110
+ @custom_field.offset = 1
111
+ assert_equal({ :offset => 1 }, @custom_field.configuration)
112
+ end
113
+
114
+ def test_should_get_offset
115
+ @custom_field.offset = 1
116
+ assert_equal 1, @custom_field.offset
117
+ end
118
+
119
+ def test_should_get_offset_predicate
120
+ @custom_field.offset = 1
121
+ assert_equal true, @custom_field.offset?
122
+ end
123
+
124
+ def test_should_type_cast_offset_as_integer
125
+ @custom_field.offset = '1'
126
+ assert_equal 1, @custom_field.offset
127
+ end
128
+
129
+ def test_should_set_amount
130
+ @custom_field.amount = 1.0
131
+ assert_equal({ :amount => 1.0 }, @custom_field.configuration)
132
+ end
133
+
134
+ def test_should_get_amount
135
+ @custom_field.amount = 1.0
136
+ assert_equal 1.0, @custom_field.amount
137
+ end
138
+
139
+ def test_should_get_amount_predicate
140
+ @custom_field.amount = 1.0
141
+ assert_equal true, @custom_field.amount?
142
+ end
143
+
144
+ def test_should_get_nil_amount
145
+ assert_equal nil, @custom_field.amount
146
+ end
147
+
148
+ def test_should_type_cast_amount_as_float
149
+ @custom_field.amount = '1'
150
+ assert_equal 1.0, @custom_field.amount
151
+
152
+ @custom_field.amount = 1
153
+ assert_equal 1.0, @custom_field.amount
154
+ end
155
+
156
+ def test_should_set_required_in_configuration2
157
+ @custom_field.required = true
158
+ assert_equal true, @custom_field.configuration2[:required]
159
+ end
160
+
161
+ def test_should_get_required
162
+ @custom_field.required = true
163
+ assert_equal true, @custom_field.required
164
+ end
165
+
166
+ def test_should_get_required_predicate
167
+ @custom_field.required = false
168
+ assert_equal false, @custom_field.required?
169
+ end
170
+
171
+ def test_should_type_cast_required_as_boolean
172
+ assert_equal false, @custom_field.required
173
+
174
+ @custom_field.required = false
175
+ assert_equal false, @custom_field.required
176
+
177
+ @custom_field.required = 0
178
+ assert_equal false, @custom_field.required
179
+
180
+ @custom_field.required = '0'
181
+ assert_equal false, @custom_field.required
182
+
183
+ @custom_field.required = true
184
+ assert_equal true, @custom_field.required
185
+
186
+ @custom_field.required = 1
187
+ assert_equal true, @custom_field.required
188
+
189
+ @custom_field.required = '1'
190
+ assert_equal true, @custom_field.required
191
+
192
+ @custom_field.required = ''
193
+ assert_equal false, @custom_field.required
194
+ end
195
+
196
+ def test_should_set_price
197
+ @custom_field.price = BigDecimal.new('1.0')
198
+ assert_equal({ :price => BigDecimal.new('1.0') }, @custom_field.configuration)
199
+ end
200
+
201
+ def test_should_get_price
202
+ @custom_field.price = BigDecimal.new('1.0')
203
+ assert_equal BigDecimal.new('1.0'), @custom_field.price
204
+ end
205
+
206
+ def test_should_get_price_predicate
207
+ @custom_field.price = BigDecimal.new('1.0')
208
+ assert_equal true, @custom_field.price?
209
+ end
210
+
211
+ def test_should_type_cast_price_as_decimal
212
+ @custom_field.price = '1.0'
213
+ assert_equal BigDecimal.new('1.0'), @custom_field.price
214
+ end
215
+
216
+ def test_should_get_default_price
217
+ assert_equal BigDecimal.new('5.0'), @custom_field.price
218
+ @custom_field.price = '1.0'
219
+ assert_equal BigDecimal.new('1.0'), @custom_field.price
220
+ end
221
+
222
+ def test_should_get_sale_price
223
+ assert_equal BigDecimal.new('2.5'), @custom_field.sale_price
224
+ @custom_field.price = '1.0'
225
+ assert_equal BigDecimal.new('0.5'), @custom_field.sale_price
226
+ @custom_field.sale_price = '0.8'
227
+ assert_equal BigDecimal.new('0.8'), @custom_field.sale_price
228
+ end
229
+
230
+ def test_should_get_sale_price_predicate
231
+ assert_equal true, @custom_field.sale_price?
232
+ end
233
+
234
+ def test_should_set_sizes
235
+ @custom_field.sizes = %w(XS S M L XL XXL)
236
+ assert_equal({ :sizes => %w(XS S M L XL XXL) }, @custom_field.configuration)
237
+ end
238
+
239
+ def test_should_get_sizes
240
+ @custom_field.sizes = %w(XS S M L XL XXL)
241
+ assert_equal %w(XS S M L XL XXL), @custom_field.sizes
242
+ end
243
+
244
+ def test_should_get_sizes_predicate?
245
+ @custom_field.sizes = %w(XS S M L XL XXL)
246
+ assert_equal true, @custom_field.sizes?
247
+ end
248
+
249
+ def test_should_type_cast_sizes_as_array
250
+ @custom_field.sizes = 'XXL'
251
+ assert_equal %w(XXL), @custom_field.sizes
252
+ end
253
+
254
+ def test_should_edit_sizes_in_place
255
+ @custom_field.sizes = %w(XS S M L XL XXL)
256
+ @custom_field.sizes.delete("XXL")
257
+ assert_equal %w(XS S M L XL), @custom_field.sizes
258
+ @custom_field.sizes << "XXL"
259
+ assert_equal %w(XS S M L XL XXL), @custom_field.sizes
260
+ end
261
+
262
+ def test_should_raise_exception_if_attribute_option_is_not_passed
263
+ assert_raises Huberry::HattrAccessor::MissingAttributeError do
264
+ CustomField.hattr_accessor :test
265
+ end
266
+ end
267
+
268
+ def test_should_not_overwrite_existing_reader
269
+ assert_equal true, @custom_field.configuration2[:some_default_reader_value]
270
+ end
271
+
272
+ def test_should_not_overwrite_existing_writer
273
+ @custom_field.configuration2 = {}
274
+ assert_equal true, @custom_field.configuration2[:some_default_writer_value]
275
+ end
276
+
277
+ def test_should_add_before_type_cast_reader
278
+ assert CustomField.method_defined?(:name_before_type_cast)
279
+ assert CustomField.method_defined?(:unit_before_type_cast)
280
+ assert CustomField.method_defined?(:offset_before_type_cast)
281
+ assert CustomField.method_defined?(:amount_before_type_cast)
282
+ assert CustomField.method_defined?(:price_before_type_cast)
283
+ assert CustomField.method_defined?(:required_before_type_cast)
284
+ end
285
+
286
+ end
metadata ADDED
@@ -0,0 +1,66 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: hattr_accessor
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Sean Huber
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-01-06 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Allows you to define attr_accessors that reference members of a hash
17
+ email: shuber@huberry.com
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - README.markdown
24
+ files:
25
+ - CHANGELOG
26
+ - MIT-LICENSE
27
+ - README.markdown
28
+ - Rakefile
29
+ - VERSION
30
+ - hattr_accessor.gemspec
31
+ - lib/hattr_accessor.rb
32
+ - test/active_record_test.rb
33
+ - test/fixtures/manufacturers.yml
34
+ - test/fixtures/products.yml
35
+ - test/hattr_accessor_test.rb
36
+ has_rdoc: true
37
+ homepage: http://github.com/shuber/hattr_accessor
38
+ licenses: []
39
+
40
+ post_install_message:
41
+ rdoc_options:
42
+ - --charset=UTF-8
43
+ require_paths:
44
+ - lib
45
+ required_ruby_version: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: "0"
50
+ version:
51
+ required_rubygems_version: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: "0"
56
+ version:
57
+ requirements: []
58
+
59
+ rubyforge_project:
60
+ rubygems_version: 1.3.5
61
+ signing_key:
62
+ specification_version: 3
63
+ summary: Allows you to define attr_accessors that reference members of a hash
64
+ test_files:
65
+ - test/active_record_test.rb
66
+ - test/hattr_accessor_test.rb