attribute_helpers 0.1.2 → 0.1.3

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