virtus 1.0.0.beta8 → 1.0.0.rc1

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.
@@ -14,10 +14,6 @@ describe Virtus::ValueObject do
14
14
  expect(subject.class.attribute_set[:name]).to_not be_public_writer
15
15
  end
16
16
 
17
- it 'disallows mass-assignment' do
18
- expect(subject.private_methods).to include(:attributes=)
19
- end
20
-
21
17
  it 'disallows cloning' do
22
18
  expect(subject.clone).to be(subject)
23
19
  end
@@ -41,10 +37,20 @@ describe Virtus::ValueObject do
41
37
  end
42
38
  end
43
39
 
40
+ share_examples_for 'a valid value object with mass-assignment turned on' do
41
+ subject { model.new }
42
+
43
+ it 'disallows mass-assignment' do
44
+ expect(subject.private_methods).to include(:attributes=)
45
+ end
46
+ end
47
+
44
48
  context 'using new values {} block' do
45
49
  let(:model) {
50
+ model = Virtus.value_object(:coerce => false, :mass_assignment => mass_assignment)
51
+
46
52
  Class.new {
47
- include Virtus.value_object(:coerce => false)
53
+ include model
48
54
 
49
55
  def self.name
50
56
  'Model'
@@ -57,30 +63,41 @@ describe Virtus::ValueObject do
57
63
  }
58
64
  }
59
65
 
60
- it_behaves_like 'a valid value object'
66
+ context 'without mass-assignment' do
67
+ let(:mass_assignment) { false }
61
68
 
62
- context 'with a model subclass' do
63
- let(:subclass) {
64
- Class.new(model) {
65
- values do
66
- attribute :email, String
67
- end
69
+ it_behaves_like 'a valid value object'
70
+ end
71
+
72
+ context 'with mass-assignment' do
73
+ let(:mass_assignment) { true }
74
+
75
+ it_behaves_like 'a valid value object'
76
+ it_behaves_like 'a valid value object with mass-assignment turned on'
77
+
78
+ context 'with a model subclass' do
79
+ let(:subclass) {
80
+ Class.new(model) {
81
+ values do
82
+ attribute :email, String
83
+ end
84
+ }
68
85
  }
69
- }
70
86
 
71
- it_behaves_like 'a valid value object' do
72
- subject { subclass.new(attributes) }
87
+ it_behaves_like 'a valid value object' do
88
+ subject { subclass.new(attributes) }
73
89
 
74
- let(:attributes) { Hash[:id => 1, :name => 'Jane Doe', :email => 'jane@doe.com'] }
90
+ let(:attributes) { Hash[:id => 1, :name => 'Jane Doe', :email => 'jane@doe.com'] }
75
91
 
76
- its(:email) { should eql('jane@doe.com') }
92
+ its(:email) { should eql('jane@doe.com') }
77
93
 
78
- it 'sets private writers for additional values' do
79
- expect(subclass.attribute_set[:email]).to_not be_public_writer
80
- end
94
+ it 'sets private writers for additional values' do
95
+ expect(subclass.attribute_set[:email]).to_not be_public_writer
96
+ end
81
97
 
82
- it 'defines valid #== for a subclass' do
83
- expect(subject == subject.class.new(attributes.merge(:id => 2))).to be(false)
98
+ it 'defines valid #== for a subclass' do
99
+ expect(subject == subject.class.new(attributes.merge(:id => 2))).to be(false)
100
+ end
84
101
  end
85
102
  end
86
103
  end
data/virtus.gemspec CHANGED
@@ -10,6 +10,7 @@ Gem::Specification.new do |gem|
10
10
  gem.description = "Attributes on Steroids for Plain Old Ruby Objects"
11
11
  gem.summary = gem.description
12
12
  gem.homepage = "https://github.com/solnic/virtus"
13
+ gem.license = 'MIT'
13
14
 
14
15
  gem.require_paths = [ "lib" ]
15
16
  gem.files = `git ls-files`.split("\n")
@@ -19,5 +20,5 @@ Gem::Specification.new do |gem|
19
20
  gem.add_dependency('descendants_tracker', '~> 0.0.1')
20
21
  gem.add_dependency('equalizer', '~> 0.0.7')
21
22
  gem.add_dependency('coercible', '~> 0.2')
22
- gem.add_dependency('axiom-types', '~> 0.0.3')
23
+ gem.add_dependency('axiom-types', '~> 0.0.4')
23
24
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: virtus
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0.beta8
4
+ version: 1.0.0.rc1
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-09-28 00:00:00.000000000 Z
12
+ date: 2013-10-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: descendants_tracker
@@ -66,7 +66,7 @@ dependencies:
66
66
  requirements:
67
67
  - - ~>
68
68
  - !ruby/object:Gem::Version
69
- version: 0.0.3
69
+ version: 0.0.4
70
70
  type: :runtime
71
71
  prerelease: false
72
72
  version_requirements: !ruby/object:Gem::Requirement
@@ -74,7 +74,7 @@ dependencies:
74
74
  requirements:
75
75
  - - ~>
76
76
  - !ruby/object:Gem::Version
77
- version: 0.0.3
77
+ version: 0.0.4
78
78
  description: Attributes on Steroids for Plain Old Ruby Objects
79
79
  email:
80
80
  - piotr.solnica@gmail.com
@@ -122,6 +122,8 @@ files:
122
122
  - lib/virtus/attribute/lazy_default.rb
123
123
  - lib/virtus/attribute/strict.rb
124
124
  - lib/virtus/attribute_set.rb
125
+ - lib/virtus/builder.rb
126
+ - lib/virtus/builder/hook_context.rb
125
127
  - lib/virtus/class_inclusions.rb
126
128
  - lib/virtus/class_methods.rb
127
129
  - lib/virtus/configuration.rb
@@ -129,7 +131,6 @@ files:
129
131
  - lib/virtus/extensions.rb
130
132
  - lib/virtus/instance_methods.rb
131
133
  - lib/virtus/model.rb
132
- - lib/virtus/module_builder.rb
133
134
  - lib/virtus/module_extensions.rb
134
135
  - lib/virtus/support/equalizer.rb
135
136
  - lib/virtus/support/options.rb
@@ -145,6 +146,7 @@ files:
145
146
  - spec/integration/embedded_value_spec.rb
146
147
  - spec/integration/extending_objects_spec.rb
147
148
  - spec/integration/hash_attributes_coercion_spec.rb
149
+ - spec/integration/inheritance_spec.rb
148
150
  - spec/integration/injectible_coercers_spec.rb
149
151
  - spec/integration/mass_assignment_with_accessors_spec.rb
150
152
  - spec/integration/overriding_virtus_spec.rb
@@ -201,7 +203,8 @@ files:
201
203
  - spec/unit/virtus/value_object_spec.rb
202
204
  - virtus.gemspec
203
205
  homepage: https://github.com/solnic/virtus
204
- licenses: []
206
+ licenses:
207
+ - MIT
205
208
  post_install_message:
206
209
  rdoc_options: []
207
210
  require_paths:
@@ -1,192 +0,0 @@
1
- module Virtus
2
-
3
- # Class to build a Virtus module with it's own configuration
4
- #
5
- # This allows for individual Virtus modules to be included in
6
- # classes and not impacted by the global Virtus configuration,
7
- # which is implemented using Virtus::Configuration.
8
- #
9
- # @private
10
- class ExtensionBuilder
11
-
12
- # Return module
13
- #
14
- # @return [Module]
15
- #
16
- # @api private
17
- attr_reader :module
18
-
19
- # Return configuration
20
- #
21
- # @return [Configuration]
22
- #
23
- # @api private
24
- attr_reader :configuration
25
-
26
- # Builds a new Virtus module
27
- #
28
- # The block is passed to Virtus::Configuration
29
- #
30
- # @example
31
- # ModuleBuilder.call do |config|
32
- # # config settings
33
- # end
34
- #
35
- # @return [Module]
36
- #
37
- # @api public
38
- def self.call(options = {}, &block)
39
- config = Configuration.build(&block)
40
- options.each { |key, value| config.public_send("#{key}=", value) }
41
- builder = new(config)
42
- builder.add_included_hook
43
- builder.add_extended_hook
44
- builder.module
45
- end
46
-
47
- # @api private
48
- def self.pending
49
- @pending ||= []
50
- end
51
-
52
- # Initializes a new ModuleBuilder
53
- #
54
- # @param [Configuration] configuration
55
- #
56
- # @param [Module] mod
57
- #
58
- # @return [undefined]
59
- #
60
- # @api private
61
- def initialize(configuration, mod = Module.new)
62
- @configuration = configuration
63
- @module = mod
64
- end
65
-
66
- # Adds the .included hook to the anonymous module which then defines the
67
- # .attribute method to override the default.
68
- #
69
- # @return [Module]
70
- #
71
- # @api private
72
- def add_included_hook
73
- attribute_proc = attribute_method(configuration)
74
- constructor = configuration.constructor
75
- mass_assignment = configuration.mass_assignment
76
- finalize = configuration.finalize
77
- extensions = core_extensions
78
- inclusions = core_inclusions
79
-
80
- self.module.define_singleton_method :included do |object|
81
- super(object)
82
- ExtensionBuilder.pending << object unless finalize
83
- extensions.each { |mod| object.extend(mod) }
84
- inclusions.each { |mod| object.send(:include, mod) }
85
- object.send(:include, Model::Constructor) if constructor
86
- object.send(:include, Model::MassAssignment) if mass_assignment
87
- object.send(:define_singleton_method, :attribute, attribute_proc)
88
- end
89
- end
90
-
91
- # @api private
92
- def add_extended_hook
93
- attribute_proc = attribute_method(configuration)
94
- mass_assignment = configuration.mass_assignment
95
- extensions = core_inclusions + core_extensions
96
-
97
- self.module.define_singleton_method :extended do |object|
98
- super(object)
99
- extensions.each { |mod| object.extend(mod) }
100
- object.extend(Model::MassAssignment) if mass_assignment
101
- object.send :define_singleton_method, :attribute, attribute_proc
102
- end
103
- end
104
-
105
- # Wrapper for the attribute method that is used in .add_included_hook
106
- # The coercer is passed in the unused key :configured_coercer to allow the
107
- # property encapsulation by Virtus::Attribute::Coercer, where the
108
- # coercion method is known.
109
- #
110
- # @return [Proc(lambda)]
111
- #
112
- # @api private
113
- def attribute_method(configuration)
114
- module_options = self.module_options
115
-
116
- lambda do |name, type = Object, options = {}|
117
- super(name, type, module_options.merge(options))
118
- end
119
- end
120
-
121
- # @api private
122
- def module_options
123
- { :coerce => configuration.coerce,
124
- :finalize => configuration.finalize,
125
- :strict => configuration.strict,
126
- :configured_coercer => configuration.coercer }
127
- end
128
-
129
- # @api private
130
- def core_inclusions
131
- [Model::Core]
132
- end
133
-
134
- # @api private
135
- def core_extensions
136
- []
137
- end
138
-
139
- end # class ExtensionBuilder
140
-
141
- # @private
142
- class ModelExtensionBuilder < ExtensionBuilder
143
- end # ModelExtensionBuilder
144
-
145
- # @private
146
- class ModuleExtensionBuilder < ExtensionBuilder
147
-
148
- # @api private
149
- def add_included_hook
150
- attribute_proc = attribute_method(configuration)
151
- inclusions = core_inclusions
152
-
153
- inclusions << Model::Constructor if configuration.constructor
154
- inclusions << Model::MassAssignment if configuration.mass_assignment
155
-
156
- self.module.define_singleton_method :included do |object|
157
- super(object)
158
- object.extend(ModuleExtensions)
159
- object.instance_variable_set('@inclusions', inclusions)
160
- object.send(:define_singleton_method, :attribute, attribute_proc)
161
- end
162
- end
163
-
164
- end # ModuleExtensionBuilder
165
-
166
- # @private
167
- class ValueObjectExtensionBuilder < ExtensionBuilder
168
-
169
- # @api private
170
- def initialize(configuration, mod = Module.new)
171
- super
172
- @configuration.constructor = true
173
- end
174
-
175
- # @api private
176
- def module_options
177
- super.update(:writer => :private)
178
- end
179
-
180
- # @api private
181
- def core_inclusions
182
- super << ValueObject::AllowedWriterMethods << ValueObject::InstanceMethods
183
- end
184
-
185
- # @api private
186
- def core_extensions
187
- super << ValueObject::AllowedWriterMethods
188
- end
189
-
190
- end # ValueObjectBuilder
191
-
192
- end # module Virtus