attribute_extras 0.0.1

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