hattr_accessor 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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