attribute_extras 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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: eac09be8233da669f266305340d2f7c796cd8ab9
4
+ data.tar.gz: 26f61ba42a8ecde62c87e393e9ebbe97c59fcf9e
5
+ SHA512:
6
+ metadata.gz: 0a2e98ec1f27972c2edaf5966582c94c423e06a2194dcf719a26938eb0e85ca5272b69ae19d96e1065f8059f7295d9de10cecdfe84198fe28ce1d98d9efeb438
7
+ data.tar.gz: d49ae18115091d70f0f8fe6cb129e2b7cd45a9224673e06d9e9465bd02f8fb8413c59082230aab809014785948bcf7b9bff1bd21dea019a70e9feabdade20d21
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2015 Kevin Deisz
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.md ADDED
@@ -0,0 +1,80 @@
1
+ ## AttributeExtras
2
+
3
+ Use this gem for automatic behavior on attributes. It provides three class macros that can be used for managing attributes.
4
+
5
+ ### nullify_attributes
6
+
7
+ Causes attribute assignment to check for presence of the given value, and set the value accordingly.
8
+
9
+ ```ruby
10
+ class Person < ActiveRecord::Base
11
+ nullify_attributes :name
12
+ end
13
+
14
+ p = Person.new(name: ' ')
15
+ p.name # => nil
16
+ ```
17
+
18
+ ### strip_attributes
19
+
20
+ Causes string attribute assignment to strip the given value, and set the value accordingly.
21
+
22
+ ```ruby
23
+ class Person < ActiveRecord::Base
24
+ strip_attributes :name
25
+ end
26
+
27
+ p = Person.new(name: ' value ')
28
+ p.name # => 'value'
29
+ ```
30
+
31
+ ### truncate_attributes
32
+
33
+ Causes string attribute assignment to be truncated down to the maximum allowed value for that column. If `whiny` is set to true, instead adds a length validator on that attribute to cause it to error if saved.
34
+
35
+ ```ruby
36
+ class Person < ActiveRecord::Base
37
+ truncate_attributes :first_name
38
+ truncate_attributes :last_name, whiny: true
39
+ end
40
+
41
+ p = Person.new(first_name: 'a' * 500, last_name: 'a' * 500)
42
+ p.first_name # => 'a' * limit
43
+ p.save! # => ActiveRecord::RecordInvalid: Validation failed
44
+ ```
45
+
46
+ ### Inheritance
47
+
48
+ By default, attributes that you manipulate with any of the above macros will be inherited into the subclasses.
49
+
50
+ ### Other methods
51
+
52
+ For migrating values to the correct format specified, there are two methods for each macro that will enforce the format. For example, for the `nullify_attributes` macro there is the `nullify_attributes` instance method and the `nullify_attributes!` instance method. Both will set the correct values and then call their respective `save`.
53
+
54
+ For introspection, there are two methods for each macro supplied. For example, for the `nullify_attributes` macro there is the `nullified_attributes` method and the `inherited_nullified_attributes` method. Examples below:
55
+
56
+ ```ruby
57
+ class Person < ActiveRecord::Base
58
+ nullify_attributes :name
59
+ end
60
+
61
+ class Developer < Person
62
+ nullify_attributes :email
63
+ end
64
+
65
+ Person.nullified_attributes.map(&:attribute) # => [:name]
66
+ Person.inherited_nullified_attributes.map(&:attribute) # => [:name]
67
+
68
+ Developer.nullified_attributes.map(&:attribute) # => [:email]
69
+ Developer.inherited_nullified_attributes.map(&:attribute) # => [:email, :name]
70
+ ```
71
+
72
+ ## Additional information
73
+
74
+ ### Contributing
75
+
76
+ Contributions welcome! Please submit a pull request with tests.
77
+
78
+ ### Licence
79
+
80
+ MIT Licence.
data/Rakefile ADDED
@@ -0,0 +1,34 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'AttributeExtras'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+
21
+
22
+ Bundler::GemHelper.install_tasks
23
+
24
+ require 'rake/testtask'
25
+
26
+ Rake::TestTask.new(:test) do |t|
27
+ t.libs << 'lib'
28
+ t.libs << 'test'
29
+ t.pattern = 'test/**/*_test.rb'
30
+ t.verbose = false
31
+ end
32
+
33
+
34
+ task default: :test
@@ -0,0 +1,8 @@
1
+ require 'attribute_extras/base_extensions'
2
+
3
+ module AttributeExtras
4
+ autoload :Modifier, 'attribute_extras/modifier'
5
+ autoload :NullifyAttributes, 'attribute_extras/nullify_attributes'
6
+ autoload :StripAttributes, 'attribute_extras/strip_attributes'
7
+ autoload :TruncateAttributes, 'attribute_extras/truncate_attributes'
8
+ end
@@ -0,0 +1,71 @@
1
+ module AttributeExtras
2
+ module BaseExtensions
3
+
4
+ # overrides the writer to set to nil if that value is blank
5
+ def nullify_attributes(*attributes)
6
+ if self.table_exists? and (non_attributes = attributes.map(&:to_s) - self.column_names).any?
7
+ raise ArgumentError, "Invalid attributes passed to nullify_attributes: #{non_attributes.join(', ')}"
8
+ end
9
+
10
+ include ::AttributeExtras::NullifyAttributes
11
+
12
+ attributes.each do |attribute|
13
+ define_method("#{attribute}=") do |value|
14
+ write_attribute(attribute, value.presence)
15
+ end
16
+ nullified_attributes << Modifier.new(attribute)
17
+ end
18
+ end
19
+
20
+ # overrides the writer to strip the value
21
+ def strip_attributes(*attributes)
22
+ string_columns = self.columns.select { |column| column.type == :string }.map(&:name)
23
+ if self.table_exists? and (non_attributes = attributes.map(&:to_s) - string_columns).any?
24
+ raise ArgumentError, <<-MSG.squish
25
+ Invalid attributes passed to strip_attributes: #{non_attributes.join(', ')};
26
+ attributes must be string columns
27
+ MSG
28
+ end
29
+
30
+ include ::AttributeExtras::StripAttributes
31
+
32
+ attributes.each do |attribute|
33
+ define_method("#{attribute}=") do |value|
34
+ write_attribute(attribute, value.is_a?(String) ? value.strip : value)
35
+ end
36
+ stripped_attributes << Modifier.new(attribute)
37
+ end
38
+ end
39
+
40
+ # overrides the writer to truncate if that value is blank
41
+ def truncate_attributes(*attributes, whiny: false)
42
+ string_columns = self.columns.select { |column| column.type == :string && !column.limit.nil? }.map(&:name)
43
+ if self.table_exists? and (non_attributes = attributes.map(&:to_s) - string_columns).any?
44
+ raise ArgumentError, <<-MSG.squish
45
+ Invalid attributes passed to truncate_attributes: #{non_attributes.join(', ')};
46
+ attributes must be string columns that have a set limit
47
+ MSG
48
+ end
49
+
50
+ include ::AttributeExtras::TruncateAttributes
51
+
52
+ truncated_attributes
53
+ attributes.each do |attribute|
54
+ limit = self.columns_hash[attribute.to_s].limit
55
+
56
+ if whiny
57
+ validates attribute, length: { maximum: limit }
58
+ @truncated_attributes << Modifier.new(attribute, limit: limit)
59
+ else
60
+ define_method("#{attribute}=") do |value|
61
+ write_attribute(attribute, value.is_a?(String) ? value[0...limit] : value)
62
+ end
63
+ @truncated_attributes << Modifier.new(attribute)
64
+ end
65
+ end
66
+ end
67
+
68
+ end
69
+ end
70
+
71
+ ActiveRecord::Base.extend AttributeExtras::BaseExtensions
@@ -0,0 +1,14 @@
1
+ module AttributeExtras
2
+
3
+ # a container for an attribute that has been modified
4
+ class Modifier
5
+
6
+ attr_reader :attribute, :options
7
+
8
+ def initialize(attribute, options = {})
9
+ @attribute = attribute
10
+ @options = options
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,49 @@
1
+ module AttributeExtras
2
+ module NullifyAttributes
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ # inherited and current nullified attributes
8
+ def inherited_nullified_attributes
9
+ @inherited_nullified_attributes ||= begin
10
+ modifiers = []
11
+ self.ancestors.each_with_object([]) do |ancestor|
12
+ break if ancestor == ActiveRecord::Base
13
+ if ancestor.respond_to?(:nullified_attributes)
14
+ modifiers += ancestor.nullified_attributes
15
+ end
16
+ end
17
+ modifiers
18
+ end
19
+ end
20
+
21
+ # the nullified attributes for this class
22
+ def nullified_attributes
23
+ @nullified_attributes ||= []
24
+ end
25
+ end
26
+
27
+ # calls set_nullified_attributes then save
28
+ def nullify_attributes
29
+ set_nullified_attributes
30
+ self.save if self.changed?
31
+ end
32
+
33
+ # calls set_nullified_attributes then save!
34
+ def nullify_attributes!
35
+ set_nullified_attributes
36
+ self.save! if self.changed?
37
+ end
38
+
39
+ private
40
+
41
+ # apply the nullification to each specified nullified attribute
42
+ def set_nullified_attributes
43
+ self.class.inherited_nullified_attributes.each do |modifier|
44
+ attribute = modifier.attribute
45
+ self.send("#{attribute}=", self.send(attribute))
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,49 @@
1
+ module AttributeExtras
2
+ module StripAttributes
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ # inherited and current stripped attributes
8
+ def inherited_stripped_attributes
9
+ @inherited_stripped_attributes ||= begin
10
+ modifiers = []
11
+ self.ancestors.each_with_object([]) do |ancestor|
12
+ break if ancestor == ActiveRecord::Base
13
+ if ancestor.respond_to?(:stripped_attributes)
14
+ modifiers += ancestor.stripped_attributes
15
+ end
16
+ end
17
+ modifiers
18
+ end
19
+ end
20
+
21
+ # the stripped attributes for this class
22
+ def stripped_attributes
23
+ @stripped_attributes ||= []
24
+ end
25
+ end
26
+
27
+ # calls set_stripped_attributes then save
28
+ def strip_attributes
29
+ set_stripped_attributes
30
+ self.save if self.changed?
31
+ end
32
+
33
+ # calls set_stripped_attributes then save!
34
+ def strip_attributes!
35
+ set_stripped_attributes
36
+ self.save! if self.changed?
37
+ end
38
+
39
+ private
40
+
41
+ # apply the strip to each specified stripped attribute
42
+ def set_stripped_attributes
43
+ self.class.inherited_stripped_attributes.each do |modifier|
44
+ attribute = modifier.attribute
45
+ self.send("#{attribute}=", self.send(attribute))
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,53 @@
1
+ module AttributeExtras
2
+ module TruncateAttributes
3
+
4
+ extend ActiveSupport::Concern
5
+
6
+ module ClassMethods
7
+ # inherited and current truncated attributes
8
+ def inherited_truncated_attributes
9
+ @inherited_truncated_attributes ||= begin
10
+ modifiers = []
11
+ self.ancestors.each_with_object([]) do |ancestor|
12
+ break if ancestor == ActiveRecord::Base
13
+ if ancestor.respond_to?(:truncated_attributes)
14
+ modifiers += ancestor.truncated_attributes
15
+ end
16
+ end
17
+ modifiers
18
+ end
19
+ end
20
+
21
+ # the truncated attributes for this class
22
+ def truncated_attributes
23
+ @truncated_attributes ||= []
24
+ end
25
+ end
26
+
27
+ # calls set_truncated_attributes then save
28
+ def truncate_attributes
29
+ set_truncated_attributes
30
+ self.save if self.changed?
31
+ end
32
+
33
+ # calls set_truncated_attributes then save!
34
+ def truncate_attributes!
35
+ set_truncated_attributes
36
+ self.save! if self.changed?
37
+ end
38
+
39
+ private
40
+
41
+ # apply the truncation to each specified truncated attribute
42
+ def set_truncated_attributes
43
+ self.class.inherited_truncated_attributes.each do |modifier|
44
+ attribute = modifier.attribute
45
+ if modifier.options[:limit]
46
+ self.send("#{attribute}=", self.send(attribute)[0...modifier.options[:limit]])
47
+ else
48
+ self.send("#{attribute}=", self.send(attribute))
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,3 @@
1
+ module AttributeExtras
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,63 @@
1
+ require 'test_helper'
2
+
3
+ class BaseExtensionsTest < ActiveSupport::TestCase
4
+
5
+ def test_nullify_attributes_failure
6
+ assert_raises ArgumentError do
7
+ klass = address_class(:nullify_attributes, :first_line, :second_line, :third_line)
8
+ assert_not klass.respond_to?(:nullified_attributes)
9
+ end
10
+ end
11
+
12
+ def test_nullify_attributes_success
13
+ klass = address_class(:nullify_attributes, :first_line, :second_line)
14
+ assert_equal klass.nullified_attributes.map(&:attribute), [:first_line, :second_line]
15
+ assert_includes klass.instance_method(:first_line=).source_location.first, 'attribute_extras/base_extensions'
16
+ end
17
+
18
+ def test_strip_attributes_failure
19
+ assert_raises ArgumentError do
20
+ klass = address_class(:strip_attributes, :first_line, :second_line, :third_line)
21
+ assert_not klass.respond_to?(:stripped_attributes)
22
+ end
23
+ end
24
+
25
+ def test_strip_attributes_success
26
+ klass = address_class(:strip_attributes, :first_line, :second_line)
27
+ assert_equal klass.stripped_attributes.map(&:attribute), [:first_line, :second_line]
28
+ assert_includes klass.instance_method(:first_line=).source_location.first, 'attribute_extras/base_extensions'
29
+ end
30
+
31
+ def test_truncate_attributes_failure
32
+ assert_raises ArgumentError do
33
+ klass = address_class(:truncate_attributes, :first_line, :second_line, :third_line)
34
+ assert_not klass.respond_to?(:truncated_attributes)
35
+ end
36
+ end
37
+
38
+ def test_truncate_attributes_success
39
+ klass = address_class(:truncate_attributes, :first_line, :second_line)
40
+ assert_equal klass.truncated_attributes.map(&:attribute), [:first_line, :second_line]
41
+ assert_includes klass.instance_method(:first_line=).source_location.first, 'attribute_extras/base_extensions'
42
+ end
43
+
44
+ def test_truncate_attributes_success_whiny
45
+ klass = address_class(:truncate_attributes, :first_line, :second_line, whiny: true)
46
+ assert_equal klass.truncated_attributes.map(&:attribute), [:first_line, :second_line]
47
+
48
+ validator = klass.validators_on(:first_line).first
49
+ assert_kind_of ActiveModel::Validations::LengthValidator, validator
50
+ assert_equal validator.options[:maximum], COLUMN_LIMIT
51
+ end
52
+
53
+ private
54
+
55
+ # returns a newly created address class
56
+ def address_class(macro, *arguments)
57
+ Class.new(ActiveRecord::Base) do
58
+ self.table_name = 'addresses'
59
+ send(macro, *arguments)
60
+ end
61
+ end
62
+
63
+ end
@@ -0,0 +1,9 @@
1
+ require 'test_helper'
2
+
3
+ class ModifierTest < ActiveSupport::TestCase
4
+ def test_modifiers
5
+ modifier = AttributeExtras::Modifier.new(:name, limit: 255)
6
+ assert_equal modifier.attribute, :name
7
+ assert_equal modifier.options, { limit: 255 }
8
+ end
9
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class NullifyAttributesTest < ActiveSupport::TestCase
4
+ def test_nullified_name=
5
+ person = Person.new
6
+ person.nullified_name = ' '
7
+ assert_nil person.nullified_name
8
+
9
+ person.nullified_name = nil
10
+ assert_nil person.nullified_name
11
+
12
+ person.nullified_name = 'test_value'
13
+ assert_equal 'test_value', person.nullified_name
14
+ end
15
+
16
+ def test_nullify_attributes
17
+ person = Person.new
18
+ person.set_blank_attributes
19
+
20
+ assert person.nullify_attributes
21
+ assert_nil person.nullified_name
22
+ end
23
+
24
+ def test_nullify_attributes!
25
+ person = Person.new
26
+ person.set_blank_attributes
27
+
28
+ assert person.nullify_attributes!
29
+ assert_nil person.nullified_name
30
+ end
31
+
32
+ def test_nullified_attributes_inheritance
33
+ architect = Architect.new
34
+ architect.set_blank_attributes
35
+
36
+ assert architect.nullify_attributes
37
+ assert_nil architect.nullified_name
38
+ assert_nil architect.other_nullified_name
39
+ end
40
+
41
+ def test_nullified_attributes
42
+ assert_equal Person.nullified_attributes.map(&:attribute),
43
+ [:nullified_name]
44
+ assert_equal Developer.nullified_attributes.map(&:attribute), []
45
+ assert_equal Architect.nullified_attributes.map(&:attribute),
46
+ [:other_nullified_name]
47
+ end
48
+
49
+ def test_inherited_nullified_attributes
50
+ assert_equal Person.inherited_nullified_attributes.map(&:attribute),
51
+ [:nullified_name]
52
+ assert_equal Developer.inherited_nullified_attributes.map(&:attribute),
53
+ [:nullified_name]
54
+ assert_equal Architect.inherited_nullified_attributes.map(&:attribute),
55
+ [:other_nullified_name, :nullified_name]
56
+ end
57
+ end
@@ -0,0 +1,57 @@
1
+ require 'test_helper'
2
+
3
+ class StripAttributesTest < ActiveSupport::TestCase
4
+ def test_stripped_name=
5
+ person = Person.new
6
+ person.stripped_name = ' test value '
7
+ assert_equal 'test value', person.stripped_name
8
+
9
+ person.stripped_name = nil
10
+ assert_nil person.stripped_name
11
+
12
+ person.stripped_name = 'test value'
13
+ assert_equal 'test value', person.stripped_name
14
+ end
15
+
16
+ def test_strip_attributes
17
+ person = Person.new
18
+ person.set_padded_attributes
19
+
20
+ assert person.strip_attributes
21
+ assert_equal 'test value', person.stripped_name
22
+ end
23
+
24
+ def test_strip_attributes!
25
+ person = Person.new
26
+ person.set_padded_attributes
27
+
28
+ assert person.strip_attributes!
29
+ assert_equal 'test value', person.stripped_name
30
+ end
31
+
32
+ def test_stripped_attributes_inheritance
33
+ architect = Architect.new
34
+ architect.set_padded_attributes
35
+
36
+ assert architect.strip_attributes
37
+ assert_equal 'test value', architect.stripped_name
38
+ assert_equal 'test value', architect.other_stripped_name
39
+ end
40
+
41
+ def test_stripped_attributes
42
+ assert_equal Person.stripped_attributes.map(&:attribute),
43
+ [:stripped_name]
44
+ assert_equal Developer.stripped_attributes.map(&:attribute), []
45
+ assert_equal Architect.stripped_attributes.map(&:attribute),
46
+ [:other_stripped_name]
47
+ end
48
+
49
+ def test_inherited_stripped_attributes
50
+ assert_equal Person.inherited_stripped_attributes.map(&:attribute),
51
+ [:stripped_name]
52
+ assert_equal Developer.inherited_stripped_attributes.map(&:attribute),
53
+ [:stripped_name]
54
+ assert_equal Architect.inherited_stripped_attributes.map(&:attribute),
55
+ [:other_stripped_name, :stripped_name]
56
+ end
57
+ end
@@ -0,0 +1,80 @@
1
+ COLUMN_LIMIT = 255
2
+
3
+ ActiveRecord::Schema.define do
4
+ create_table :people, force: true do |t|
5
+ t.string :nullified_name
6
+ t.string :other_nullified_name
7
+
8
+ t.string :stripped_name
9
+ t.string :other_stripped_name
10
+
11
+ t.string :truncated_name, limit: COLUMN_LIMIT
12
+ t.string :truncated_whiny_name, limit: COLUMN_LIMIT
13
+ t.string :other_truncated_name, limit: COLUMN_LIMIT
14
+ end
15
+
16
+ create_table :addresses, force: true do |t|
17
+ t.string :first_line, limit: COLUMN_LIMIT
18
+ t.string :second_line, limit: COLUMN_LIMIT
19
+ end
20
+ end
21
+
22
+ class Person < ActiveRecord::Base
23
+ nullify_attributes :nullified_name
24
+ strip_attributes :stripped_name
25
+ truncate_attributes :truncated_name
26
+ truncate_attributes :truncated_whiny_name, whiny: true
27
+
28
+ def set_blank_attributes
29
+ write_attribute(:nullified_name, ' ')
30
+ save
31
+ end
32
+
33
+ def set_long_attributes
34
+ write_attribute(:truncated_name, self.class.long_value)
35
+ write_attribute(:truncated_whiny_name, self.class.long_value)
36
+ save(validate: false)
37
+ end
38
+
39
+ def set_padded_attributes
40
+ write_attribute(:stripped_name, ' test value ')
41
+ save
42
+ end
43
+
44
+ class << self
45
+ def short_value
46
+ @short_value ||= ('a' * COLUMN_LIMIT)
47
+ end
48
+
49
+ def long_value
50
+ @long_value ||= ('a' * 500)
51
+ end
52
+ end
53
+ end
54
+
55
+ class Developer < Person; end
56
+
57
+ class Architect < Developer
58
+ nullify_attributes :other_nullified_name
59
+ strip_attributes :other_stripped_name
60
+ truncate_attributes :other_truncated_name
61
+
62
+ def set_blank_attributes
63
+ write_attribute(:nullified_name, ' ')
64
+ write_attribute(:other_nullified_name, ' ')
65
+ save
66
+ end
67
+
68
+ def set_long_attributes
69
+ write_attribute(:truncated_name, self.class.long_value)
70
+ write_attribute(:truncated_whiny_name, self.class.long_value)
71
+ write_attribute(:other_truncated_name, self.class.long_value)
72
+ save
73
+ end
74
+
75
+ def set_padded_attributes
76
+ write_attribute(:stripped_name, ' test value ')
77
+ write_attribute(:other_stripped_name, ' test value ')
78
+ save
79
+ end
80
+ end
@@ -0,0 +1,25 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+
3
+ begin
4
+ require 'bundler/inline'
5
+ rescue LoadError => e
6
+ $stderr.puts 'Bundler version 1.10 or later is required. Please update your Bundler'
7
+ raise e
8
+ end
9
+
10
+ gemfile(true) do
11
+ source 'https://rubygems.org'
12
+ gem 'activerecord'
13
+ gem 'sqlite3'
14
+ end
15
+
16
+ require 'active_record'
17
+ require 'minitest/autorun'
18
+ require 'logger'
19
+ require 'attribute_extras'
20
+
21
+ ActiveRecord::Base.establish_connection(adapter: 'sqlite3', database: ':memory:')
22
+ ActiveRecord::Base.logger = Logger.new(STDOUT)
23
+ ActiveSupport.test_order = :sorted
24
+
25
+ require 'test_classes'
@@ -0,0 +1,69 @@
1
+ require 'test_helper'
2
+
3
+ class TruncateAttributesTest < ActiveSupport::TestCase
4
+ def test_truncated_name=
5
+ person = Person.new
6
+ person.truncated_name = Person.long_value
7
+ assert_equal Person.short_value, person.truncated_name
8
+
9
+ person.truncated_name = nil
10
+ assert_equal nil, person.truncated_name
11
+
12
+ person.truncated_name = 'test_value'
13
+ assert_equal 'test_value', person.truncated_name
14
+ end
15
+
16
+ def test_truncated_whiny_name_validation
17
+ person = Person.new
18
+ person.truncated_whiny_name = Person.long_value
19
+
20
+ assert_not person.save
21
+ assert_equal ["is too long (maximum is #{COLUMN_LIMIT} characters)"],
22
+ person.errors[:truncated_whiny_name]
23
+ end
24
+
25
+ def test_truncate_attributes
26
+ person = Person.new
27
+ person.set_long_attributes
28
+
29
+ assert person.truncate_attributes
30
+ assert_equal Person.short_value, person.truncated_name
31
+ assert_equal Person.short_value, person.truncated_whiny_name
32
+ end
33
+
34
+ def test_truncate_attributes!
35
+ person = Person.new
36
+ person.set_long_attributes
37
+
38
+ assert person.truncate_attributes!
39
+ assert_equal Person.short_value, person.truncated_name
40
+ assert_equal Person.short_value, person.truncated_whiny_name
41
+ end
42
+
43
+ def test_truncated_attributes_inheritance
44
+ architect = Architect.new
45
+ architect.set_long_attributes
46
+
47
+ assert architect.truncate_attributes
48
+ assert_equal Person.short_value, architect.truncated_name
49
+ assert_equal Person.short_value, architect.truncated_whiny_name
50
+ assert_equal Person.short_value, architect.other_truncated_name
51
+ end
52
+
53
+ def test_truncated_attributes
54
+ assert_equal Person.truncated_attributes.map(&:attribute),
55
+ [:truncated_name, :truncated_whiny_name]
56
+ assert_equal Developer.truncated_attributes.map(&:attribute), []
57
+ assert_equal Architect.truncated_attributes.map(&:attribute),
58
+ [:other_truncated_name]
59
+ end
60
+
61
+ def test_inherited_truncated_attributes
62
+ assert_equal Person.inherited_truncated_attributes.map(&:attribute),
63
+ [:truncated_name, :truncated_whiny_name]
64
+ assert_equal Developer.inherited_truncated_attributes.map(&:attribute),
65
+ [:truncated_name, :truncated_whiny_name]
66
+ assert_equal Architect.inherited_truncated_attributes.map(&:attribute),
67
+ [:other_truncated_name, :truncated_name, :truncated_whiny_name]
68
+ end
69
+ end
metadata ADDED
@@ -0,0 +1,97 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: attribute_extras
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Kevin Deisz
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-07-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">"
18
+ - !ruby/object:Gem::Version
19
+ version: '3'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">"
25
+ - !ruby/object:Gem::Version
26
+ version: '3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: sqlite3
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ description: Overrides writers methods on ActiveRecord classes to allow for different
42
+ behavior such as nullifying, stripping, and truncating.
43
+ email:
44
+ - kevin.deisz@gmail.com
45
+ executables: []
46
+ extensions: []
47
+ extra_rdoc_files: []
48
+ files:
49
+ - MIT-LICENSE
50
+ - README.md
51
+ - Rakefile
52
+ - lib/attribute_extras.rb
53
+ - lib/attribute_extras/base_extensions.rb
54
+ - lib/attribute_extras/modifier.rb
55
+ - lib/attribute_extras/nullify_attributes.rb
56
+ - lib/attribute_extras/strip_attributes.rb
57
+ - lib/attribute_extras/truncate_attributes.rb
58
+ - lib/attribute_extras/version.rb
59
+ - test/base_extensions_test.rb
60
+ - test/modifier_test.rb
61
+ - test/nullify_attributes_test.rb
62
+ - test/strip_attributes_test.rb
63
+ - test/test_classes.rb
64
+ - test/test_helper.rb
65
+ - test/truncate_attributes_test.rb
66
+ homepage: https://github.com/kddeisz/attribute_extras
67
+ licenses:
68
+ - MIT
69
+ metadata: {}
70
+ post_install_message:
71
+ rdoc_options: []
72
+ require_paths:
73
+ - lib
74
+ required_ruby_version: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - ">="
77
+ - !ruby/object:Gem::Version
78
+ version: '0'
79
+ required_rubygems_version: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ requirements: []
85
+ rubyforge_project:
86
+ rubygems_version: 2.4.5
87
+ signing_key:
88
+ specification_version: 4
89
+ summary: Extra macros for auto attribute manipulation.
90
+ test_files:
91
+ - test/base_extensions_test.rb
92
+ - test/modifier_test.rb
93
+ - test/nullify_attributes_test.rb
94
+ - test/strip_attributes_test.rb
95
+ - test/test_classes.rb
96
+ - test/test_helper.rb
97
+ - test/truncate_attributes_test.rb