attribute_helpers 0.1.2 → 0.1.3

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 30c3ad3c1054e35f25b381e6ac561ee6af2668a5
4
- data.tar.gz: 073eaa8bc7744dab2d6486621a910fb0bf8c869b
3
+ metadata.gz: 371fc65b415471c2e41907947fd5798831fc912c
4
+ data.tar.gz: 339b8e18db7b2a4a8458a9b2d7f1043378d9c33f
5
5
  SHA512:
6
- metadata.gz: 45ea30653a242b3686a1438922daf8ca7328465399260b6cfb5c9b36a2f9d3be19331c8ab7c2cb51040a5775a0f2538e0e028e9a34ad051ca6e142c553b5919c
7
- data.tar.gz: d857d77b23a768c48d4c76a18448ad58d04ba47336ef892e5b26df0466eeefbd5779d60e62cc7828614dad7575d865855ca5b1f1b443cc5d2afbd2abb2f2c1de
6
+ metadata.gz: 98646509854eea74a47cdd40b1bf5e8a7eb966ef4bb75a405718ab9e050809cf112e1f6bc413063e182d298690a8b1159cb82a6e8a706da734900c0eaa349e53
7
+ data.tar.gz: 72dc5752acf0472e47c9c92fd580a0e5cf2a5b8c95cd3ebe08c4e0c1f29bb1b21c4e133c3536412af87f456234c009fd05344f4a3da19a6965c717002cb498e4
@@ -2,6 +2,9 @@ language: ruby
2
2
  rvm:
3
3
  - 2.0.0
4
4
  - 2.1.4
5
+ - 2.2.0
6
+ before_install:
7
+ - gem update bundler
5
8
  script: bundle exec rspec
6
9
  addons:
7
10
  code_climate:
@@ -27,4 +27,5 @@ Gem::Specification.new do |spec|
27
27
  spec.add_development_dependency "rspec", "~> 3.1"
28
28
  spec.add_development_dependency "rubocop", "~> 0.28"
29
29
  spec.add_development_dependency "temping", "~> 3.2"
30
+ spec.add_development_dependency "sqlite3", "~> 1.3"
30
31
  end
@@ -6,60 +6,49 @@ require "attribute_helpers/version"
6
6
  # the database and your application code.
7
7
 
8
8
  module AttributeHelpers
9
- # This module needs to be prepended to work in ActiveRecord classes. This is
10
- # because ActiveRecord doesn't have accessors/mutators defined until an
11
- # instance is created, which means we need to use the prepend + super()
12
- # pattern because attempts to use instance_method + binding will fail since
13
- # instance_method will not find the method in the class context as it will not
14
- # exist until it is dynamically created when an instance is created. Prepend
15
- # works for us because it inserts the behavior *below* the class in the
16
- # inheritance hierarchy, so we can access the default ActiveRecord accessors/
17
- # mutators through the use of super().
18
- # More information here: http://stackoverflow.com/a/4471202/1103543
19
- def self.prepended(klass)
20
- # We need to store the module in a variable for use when we're in the class
21
- # context.
22
- me = self
23
-
24
- # Marks attributes as storing symbol values, providing setters and getters
25
- # for the attributes that will allow the application to use them as symbols
26
- # but store them internally as strings.
27
- # @param attrs [*Symbol] a list of the attributes that store symbols
28
- klass.define_singleton_method :attr_symbol do |*attrs|
29
- # Overwrite each attribute's methods.
30
- attrs.each do |attr|
31
- # Overwrite the accessor.
32
- me.send(:define_method, attr) do
33
- val = super()
34
- val && val.to_sym
35
- end
9
+ def attr_symbol(*attrs)
10
+ transform_attributes(*attrs, &:to_sym)
11
+ end
36
12
 
37
- # Overwrite the mutator.
38
- me.send(:define_method, "#{attr}=") do |val|
39
- super(val && val.to_s)
40
- end
41
- end
42
- end
13
+ def attr_class(*attrs)
14
+ transform_attributes(*attrs) { |val| Kernel.const_get(val) }
15
+ end
43
16
 
44
- # Marks attributes as storing class values, providing setters and getters
45
- # for the attributes that will allow the application to use them as classes
46
- # but store them internally as strings.
47
- # @param attrs [*Symbol] a list of the attributes that store classes
48
- klass.define_singleton_method :attr_class do |*attrs|
49
- # Overwrite each attribute's methods.
17
+ # Implementation Note
18
+ # -------------------
19
+ # The transformers above all work by creating an anonymous module for each
20
+ # group of attributes that gets prepended into the class the AttributeHelpers
21
+ # module is included into. These modules need to be defined at method call
22
+ # time to avoid leaking the overrided methods into other classes this module
23
+ # is included in.
24
+ #
25
+ # This anonymous module needs to be prepended to work in ActiveRecord classes.
26
+ # This is because ActiveRecord doesn't have accessors/mutators defined until
27
+ # an instance is created, which means we need to use the prepend pattern
28
+ # because attempts to use instance_method instance_method will not find the
29
+ # method in the class context as it will not exist until it is dynamically
30
+ # created when an instance is created. Prepend works for us because it inserts
31
+ # the behavior *below* the class in the inheritance hierarchy, so we can
32
+ # access the default ActiveRecord accessors/ mutators through the use of
33
+ # super().
34
+ #
35
+ # More information here: http://stackoverflow.com/a/4471202/1103543
36
+ def transform_attributes(*attrs, &block)
37
+ transformer = Module.new do
50
38
  attrs.each do |attr|
51
39
  # Overwrite the accessor.
52
- # @raise [NameError] if the string can't be constantized
53
- me.send(:define_method, attr) do
40
+ define_method(attr) do
54
41
  val = super()
55
- val && Kernel.const_get(val)
42
+ val && block.call(val)
56
43
  end
57
44
 
58
45
  # Overwrite the mutator.
59
- me.send(:define_method, "#{attr}=") do |val|
46
+ define_method("#{attr}=") do |val|
60
47
  super(val && val.to_s)
61
48
  end
62
49
  end
63
50
  end
51
+
52
+ prepend transformer
64
53
  end
65
54
  end
@@ -1,3 +1,3 @@
1
1
  module AttributeHelpers
2
- VERSION = "0.1.2"
2
+ VERSION = "0.1.3"
3
3
  end
@@ -3,16 +3,30 @@ require "spec_helper"
3
3
  RSpec.context "in an ActiveRecord class" do
4
4
  Temping.create :active_record_test_class do
5
5
  with_columns do |t|
6
+ t.integer :other_symbol_attr
7
+ t.integer :other_class_attr
6
8
  t.string :symbol_attr
7
9
  t.string :class_attr
8
10
  end
9
11
 
10
- prepend AttributeHelpers
12
+ extend AttributeHelpers
11
13
 
12
14
  attr_symbol :symbol_attr
13
15
  attr_class :class_attr
14
16
  end
15
17
 
18
+ Temping.create :other_active_record_test_class do
19
+ with_columns do |t|
20
+ t.string :other_symbol_attr
21
+ t.string :other_class_attr
22
+ end
23
+
24
+ extend AttributeHelpers
25
+
26
+ attr_symbol :other_symbol_attr
27
+ attr_class :other_class_attr
28
+ end
29
+
16
30
  let(:test_obj) { ActiveRecordTestClass.new }
17
31
 
18
32
  describe ".attr_symbol" do
@@ -48,6 +62,13 @@ RSpec.context "in an ActiveRecord class" do
48
62
  expect(test_obj[:symbol_attr]).to be_nil
49
63
  end
50
64
  end
65
+
66
+ context "with attributes that overlap with another class" do
67
+ it "does not overwrite other attributes" do
68
+ test_obj.other_symbol_attr = 12345
69
+ expect(test_obj.other_symbol_attr).to eq 12345
70
+ end
71
+ end
51
72
  end
52
73
 
53
74
  describe ".attr_class" do
@@ -94,5 +115,12 @@ RSpec.context "in an ActiveRecord class" do
94
115
  expect(test_obj[:class_attr]).to be_nil
95
116
  end
96
117
  end
118
+
119
+ context "with attributes that overlap with another class" do
120
+ it "does not overwrite other attributes" do
121
+ test_obj.other_class_attr = 12345
122
+ expect(test_obj.other_class_attr).to eq 12345
123
+ end
124
+ end
97
125
  end
98
126
  end
@@ -2,21 +2,33 @@ require "spec_helper"
2
2
 
3
3
  RSpec.context "in a pure Ruby class" do
4
4
  class RubyTestClass
5
- prepend AttributeHelpers
5
+ extend AttributeHelpers
6
6
 
7
7
  attr_accessor :symbol_attr
8
8
  attr_accessor :class_attr
9
+ attr_accessor :other_symbol_attr
10
+ attr_accessor :other_class_attr
9
11
 
10
12
  attr_symbol :symbol_attr
11
13
  attr_class :class_attr
12
14
  end
13
15
 
16
+ class OtherRubyTestClass
17
+ extend AttributeHelpers
18
+
19
+ attr_accessor :other_symbol_attr
20
+ attr_accessor :other_class_attr
21
+
22
+ attr_symbol :other_symbol_attr
23
+ attr_class :other_class_attr
24
+ end
25
+
14
26
  let(:test_obj) { RubyTestClass.new }
15
27
 
16
28
  describe ".attr_symbol" do
17
29
  describe "getter" do
18
30
  it "translates string to symbol" do
19
- # Give it an intial value to be read.
31
+ # Give it an initial value to be read.
20
32
  test_obj.instance_variable_set(:@symbol_attr, "example")
21
33
 
22
34
  expect(test_obj.symbol_attr).to eq :example
@@ -46,6 +58,13 @@ RSpec.context "in a pure Ruby class" do
46
58
  expect(test_obj.instance_variable_get(:@symbol_attr)).to be_nil
47
59
  end
48
60
  end
61
+
62
+ context "with attributes that overlap with another class" do
63
+ it "does not overwrite other attributes" do
64
+ test_obj.other_symbol_attr = 12345
65
+ expect(test_obj.other_symbol_attr).to eq 12345
66
+ end
67
+ end
49
68
  end
50
69
 
51
70
  describe ".attr_class" do
@@ -92,5 +111,12 @@ RSpec.context "in a pure Ruby class" do
92
111
  expect(test_obj.instance_variable_get(:@class_attr)).to be_nil
93
112
  end
94
113
  end
114
+
115
+ context "with attributes that overlap with another class" do
116
+ it "does not overwrite other attributes" do
117
+ test_obj.other_class_attr = 12345
118
+ expect(test_obj.other_class_attr).to eq 12345
119
+ end
120
+ end
95
121
  end
96
122
  end
metadata CHANGED
@@ -1,113 +1,127 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: attribute_helpers
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.1.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jacob Evelyn
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-15 00:00:00.000000000 Z
11
+ date: 2015-12-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.7'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.7'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: codeclimate-test-reporter
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ~>
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
33
  version: '0.4'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ~>
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0.4'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: overcommit
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ~>
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '0.21'
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ~>
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0.21'
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rake
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ~>
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
61
  version: '10.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ~>
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
68
  version: '10.0'
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
- - - ~>
73
+ - - "~>"
74
74
  - !ruby/object:Gem::Version
75
75
  version: '3.1'
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ~>
80
+ - - "~>"
81
81
  - !ruby/object:Gem::Version
82
82
  version: '3.1'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: rubocop
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
- - - ~>
87
+ - - "~>"
88
88
  - !ruby/object:Gem::Version
89
89
  version: '0.28'
90
90
  type: :development
91
91
  prerelease: false
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ~>
94
+ - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.28'
97
97
  - !ruby/object:Gem::Dependency
98
98
  name: temping
99
99
  requirement: !ruby/object:Gem::Requirement
100
100
  requirements:
101
- - - ~>
101
+ - - "~>"
102
102
  - !ruby/object:Gem::Version
103
103
  version: '3.2'
104
104
  type: :development
105
105
  prerelease: false
106
106
  version_requirements: !ruby/object:Gem::Requirement
107
107
  requirements:
108
- - - ~>
108
+ - - "~>"
109
109
  - !ruby/object:Gem::Version
110
110
  version: '3.2'
111
+ - !ruby/object:Gem::Dependency
112
+ name: sqlite3
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '1.3'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '1.3'
111
125
  description: Provides auto-serialization of simple Ruby types that databases do not
112
126
  support, such as symbols and classes.
113
127
  email:
@@ -116,10 +130,10 @@ executables: []
116
130
  extensions: []
117
131
  extra_rdoc_files: []
118
132
  files:
119
- - .gitignore
120
- - .overcommit.yml
121
- - .rubocop.yml
122
- - .travis.yml
133
+ - ".gitignore"
134
+ - ".overcommit.yml"
135
+ - ".rubocop.yml"
136
+ - ".travis.yml"
123
137
  - Gemfile
124
138
  - LICENSE.txt
125
139
  - README.md
@@ -140,17 +154,17 @@ require_paths:
140
154
  - lib
141
155
  required_ruby_version: !ruby/object:Gem::Requirement
142
156
  requirements:
143
- - - '>='
157
+ - - ">="
144
158
  - !ruby/object:Gem::Version
145
159
  version: '0'
146
160
  required_rubygems_version: !ruby/object:Gem::Requirement
147
161
  requirements:
148
- - - '>='
162
+ - - ">="
149
163
  - !ruby/object:Gem::Version
150
164
  version: '0'
151
165
  requirements: []
152
166
  rubyforge_project:
153
- rubygems_version: 2.2.2
167
+ rubygems_version: 2.4.8
154
168
  signing_key:
155
169
  specification_version: 4
156
170
  summary: Provides auto-serialization of simple Ruby types that databases do not support.