rom 3.1.0 → 3.2.0

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: 60084563a6e8cbda433df877fa5ceeaf6e342551
4
- data.tar.gz: 9cf468362a1adbc5b64e10d4459af3c1b05d31d6
3
+ metadata.gz: 3be503f4afdb36bf8b23b51bbafe4fad82f18146
4
+ data.tar.gz: eef4ca7433150d025b68bde69bf34a88fe9a7f3a
5
5
  SHA512:
6
- metadata.gz: bd60b6cc80d21d168fe472b4f6b52cd854e7afb368c930ae652ecb0306e9c3946d9d64d9dee7e7cdfa9e9fd66593ec8820f8ea49117cac1317c7e099f8a72a26
7
- data.tar.gz: 5db668afb63edb340bd298314eede1a5cf33f6703e5777a5f9654e62eaba8789717147f322cabbdb7d911407ec66159f18d64191a03b1ccdd9d30e5fc1dd0206
6
+ metadata.gz: bcaa8c8cda675c11f136e22598641e7e5bcaf6fe6a87bfe0a36b9eb1fea7b114b9871a272a70d66155ba8e877ea70ded5bae32084304a4d00e04ab4a26411e9f
7
+ data.tar.gz: 162ce7faa345e81153b5ce91192f34da29a2c5ccf0bf44972ad02d8d23e1383c4170b6a1850cde9043a7e3692b1811940c1fe155f53bdf5cec85944479595d83
@@ -5,11 +5,11 @@ cache: bundler
5
5
  bundler_args: --without sql benchmarks console tools
6
6
  script: "bundle exec rake ci"
7
7
  after_success:
8
- - '[ "${TRAVIS_JOB_NUMBER#*.}" = "1" ] && [ "$TRAVIS_BRANCH" = "master" ] && bundle exec codeclimate-test-reporter'
8
+ - '[ -d coverage ] && bundle exec codeclimate-test-reporter'
9
9
  rvm:
10
- - 2.4.0
11
- - 2.3
12
- - 2.2
10
+ - 2.2.6
11
+ - 2.3.3
12
+ - 2.4.1
13
13
  - rbx-3
14
14
  - jruby
15
15
  env:
@@ -1,4 +1,12 @@
1
- # v3.0.4 2017-03-01
1
+ # v3.2.0 2017-03-25
2
+
3
+ ## Changed
4
+
5
+ * `dry-initializer` was updated to `1.3`, this is a minor change, but leads to some incompabilities with existing adapters, hence `3.2.0` shall be released (flash-gordon)
6
+
7
+ [Compare v3.1.0...v3.2.0](https://github.com/rom-rb/rom/compare/v3.1.0...v3.2.0)
8
+
9
+ # v3.1.0 2017-03-01
2
10
 
3
11
  ## Added
4
12
 
@@ -8,7 +16,7 @@
8
16
  * New `ROM::Relation::Graph#with_nodes` which returns a new graph with new nodes (solnic)
9
17
  * New `ROM::Schema#empty` which returns an empty schema (solnic)
10
18
 
11
- [Compare v3.0.3...v3.0.4](https://github.com/rom-rb/rom/compare/v3.0.3...v3.0.4)
19
+ [Compare v3.0.3...v3.1.0](https://github.com/rom-rb/rom/compare/v3.0.3...v3.1.0)
12
20
 
13
21
  # v3.0.3 2017-02-24
14
22
 
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require "bundler/gem_tasks"
1
2
  require "rspec/core/rake_task"
2
3
  require "rake/testtask"
3
4
 
@@ -64,7 +64,7 @@ module ROM
64
64
  # Get relation identifier
65
65
  #
66
66
  # @example
67
- # module CreateUser < ROM::Commands::Create[:memory]
67
+ # class CreateUser < ROM::Commands::Create[:memory]
68
68
  # relation :users
69
69
  # end
70
70
  #
@@ -77,7 +77,7 @@ module ROM
77
77
  # Set relation identifier.
78
78
  #
79
79
  # @example
80
- # module CreateUser < ROM::Commands::Create[:memory]
80
+ # class CreateUser < ROM::Commands::Create[:memory]
81
81
  # relation :users
82
82
  # end
83
83
  #
@@ -91,7 +91,7 @@ module ROM
91
91
  # Get result type
92
92
  #
93
93
  # @example
94
- # module CreateUser < ROM::Commands::Create[:memory]
94
+ # class CreateUser < ROM::Commands::Create[:memory]
95
95
  # result :one
96
96
  # end
97
97
  #
@@ -104,7 +104,7 @@ module ROM
104
104
  # Set result type
105
105
  #
106
106
  # @example
107
- # module CreateUser < ROM::Commands::Create[:memory]
107
+ # class CreateUser < ROM::Commands::Create[:memory]
108
108
  # result :one
109
109
  # end
110
110
  #
@@ -119,7 +119,7 @@ module ROM
119
119
  # Get input processing function
120
120
  #
121
121
  # @example
122
- # module CreateUser < ROM::Commands::Create[:memory]
122
+ # class CreateUser < ROM::Commands::Create[:memory]
123
123
  # input -> tuple { .. }
124
124
  # end
125
125
  #
@@ -132,7 +132,7 @@ module ROM
132
132
  # Set input processing function
133
133
  #
134
134
  # @example
135
- # module CreateUser < ROM::Commands::Create[:memory]
135
+ # class CreateUser < ROM::Commands::Create[:memory]
136
136
  # input -> tuple { .. }
137
137
  # end
138
138
  #
@@ -146,7 +146,7 @@ module ROM
146
146
  # Get registration identifier
147
147
  #
148
148
  # @example
149
- # module CreateUser < ROM::Commands::Create[:memory]
149
+ # class CreateUser < ROM::Commands::Create[:memory]
150
150
  # register_as :create_user
151
151
  # end
152
152
  #
@@ -159,7 +159,7 @@ module ROM
159
159
  # Set registration identifier
160
160
  #
161
161
  # @example
162
- # module CreateUser < ROM::Commands::Create[:memory]
162
+ # class CreateUser < ROM::Commands::Create[:memory]
163
163
  # register_as :create_user
164
164
  # end
165
165
  #
@@ -171,7 +171,7 @@ module ROM
171
171
  # Check if a command class is restrictable
172
172
  #
173
173
  # @example
174
- # module UpdateUser < ROM::Commands::Update[:memory]
174
+ # class UpdateUser < ROM::Commands::Update[:memory]
175
175
  # restrictable true
176
176
  # end
177
177
  #
@@ -184,7 +184,7 @@ module ROM
184
184
  # Set if a command is restrictable
185
185
  #
186
186
  # @example
187
- # module UpdateUser < ROM::Commands::Update[:memory]
187
+ # class UpdateUser < ROM::Commands::Update[:memory]
188
188
  # restrictable true
189
189
  # end
190
190
  #
@@ -204,27 +204,27 @@ module ROM
204
204
 
205
205
  # @!attribute [r] source
206
206
  # @return [Relation] The source relation
207
- option :source, reader: true, optional: true, default: -> c { c.relation }
207
+ option :source, default: -> { relation }
208
208
 
209
- # @!attribute [r] type
209
+ # @!attribute [r] result
210
210
  # @return [Symbol] Result type, either :one or :many
211
- option :result, reader: true, type: Result
211
+ option :result, type: Result
212
212
 
213
213
  # @!attribute [r] input
214
214
  # @return [Proc, #call] Tuple processing function, typically uses Relation#input_schema
215
- option :input, reader: true
215
+ option :input
216
216
 
217
217
  # @!attribute [r] curry_args
218
218
  # @return [Array] Curried args
219
- option :curry_args, reader: true, default: -> _ { EMPTY_ARRAY }
219
+ option :curry_args, default: -> { EMPTY_ARRAY }
220
220
 
221
221
  # @!attribute [r] before
222
222
  # @return [Array<Hash>] An array with before hooks configuration
223
- option :before, Types::Coercible::Array, reader: true, as: :before_hooks, default: proc { EMPTY_ARRAY }
223
+ option :before, Types::Coercible::Array, reader: false, default: -> { self.class.before }
224
224
 
225
- # @!attribute [r] before
225
+ # @!attribute [r] after
226
226
  # @return [Array<Hash>] An array with after hooks configuration
227
- option :after, Types::Coercible::Array, reader: true, as: :after_hooks, default: proc { EMPTY_ARRAY }
227
+ option :after, Types::Coercible::Array, reader: false, default: -> { self.class.after }
228
228
 
229
229
  input Hash
230
230
  result :many
@@ -313,7 +313,7 @@ module ROM
313
313
  if curry_args.empty? && args.first.is_a?(Graph::InputEvaluator)
314
314
  Lazy[self].new(self, *args)
315
315
  else
316
- self.class.build(relation, options.merge(curry_args: args))
316
+ self.class.build(relation, **options, curry_args: args)
317
317
  end
318
318
  end
319
319
  alias_method :with, :curry
@@ -357,7 +357,7 @@ module ROM
357
357
  #
358
358
  # @api public
359
359
  def before(*hooks)
360
- self.class.new(relation, options.merge(before: before_hooks + hooks))
360
+ self.class.new(relation, **options, before: before_hooks + hooks)
361
361
  end
362
362
 
363
363
  # Return a new command with appended after hooks
@@ -368,7 +368,25 @@ module ROM
368
368
  #
369
369
  # @api public
370
370
  def after(*hooks)
371
- self.class.new(relation, options.merge(after: after_hooks + hooks))
371
+ self.class.new(relation, **options, after: after_hooks + hooks)
372
+ end
373
+
374
+ # List of before hooks
375
+ #
376
+ # @return [Array]
377
+ #
378
+ # @api public
379
+ def before_hooks
380
+ options[:before]
381
+ end
382
+
383
+ # List of after hooks
384
+ #
385
+ # @return [Array]
386
+ #
387
+ # @api public
388
+ def after_hooks
389
+ options[:after]
372
390
  end
373
391
 
374
392
  # Return a new command with other source relation
@@ -379,7 +397,7 @@ module ROM
379
397
  #
380
398
  # @api public
381
399
  def new(new_relation)
382
- self.class.build(new_relation, options.merge(source: relation))
400
+ self.class.build(new_relation, **options, source: relation)
383
401
  end
384
402
 
385
403
  # Check if this command has any hooks
@@ -26,8 +26,8 @@ module ROM
26
26
  # @api private
27
27
  param :registry, type: RegistryType
28
28
 
29
- option :mappers, reader: true, optional: true
30
- option :mapper, reader: true, optional: true
29
+ option :mappers, optional: true
30
+ option :mapper, optional: true
31
31
 
32
32
  # Try to execute a command in a block
33
33
  #
@@ -12,8 +12,17 @@ module ROM
12
12
  # @api private
13
13
  def inherited(klass)
14
14
  super
15
- klass.instance_variable_set(:'@before', before ? before.dup : [])
16
- klass.instance_variable_set(:'@after', before ? after.dup : [])
15
+ klass.instance_variable_set(:'@before', before.dup)
16
+ klass.instance_variable_set(:'@after', after.dup)
17
+ end
18
+
19
+ # Sets up the base class
20
+ #
21
+ # @api private
22
+ def self.extended(klass)
23
+ super
24
+ klass.set_hooks(:before, [])
25
+ klass.set_hooks(:after, [])
17
26
  end
18
27
 
19
28
  # Return adapter specific sub-class based on the adapter identifier
@@ -210,12 +219,11 @@ module ROM
210
219
  # @api private
211
220
  def set_hooks(type, hooks)
212
221
  ivar = :"@#{type}"
213
- value = instance_variable_get(ivar)
214
222
 
215
- if value.empty?
216
- instance_variable_set(ivar, hooks)
223
+ if instance_variable_defined?(ivar)
224
+ instance_variable_get(ivar).concat(hooks)
217
225
  else
218
- value.concat(hooks)
226
+ instance_variable_set(ivar, hooks)
219
227
  end
220
228
  end
221
229
 
@@ -26,9 +26,9 @@ module ROM
26
26
  alias_method :right, :nodes
27
27
 
28
28
  # @attr_reader [Symbol] root's relation name
29
- option :name, reader: true, default: -> g { g.root.name }
29
+ option :name, default: -> { root.name }
30
30
 
31
- option :mappers, reader: true, default: proc { MapperRegistry.new }
31
+ option :mappers, default: -> { MapperRegistry.new }
32
32
 
33
33
  # Calls root and all nodes with the result from root
34
34
  #
@@ -33,7 +33,7 @@ module ROM
33
33
 
34
34
  include Dry::Equalizer(:data)
35
35
 
36
- option :row_proc, reader: true, default: proc { |obj| obj.class.row_proc }
36
+ option :row_proc, default: -> { self.class.row_proc }
37
37
  end
38
38
  end
39
39
 
@@ -7,7 +7,7 @@ module ROM
7
7
 
8
8
  # @api private
9
9
  def self.extended(base)
10
- base.extend(Dry::Initializer::Mixin)
10
+ base.extend(Dry::Initializer[undefined: false])
11
11
  base.include(InstanceMethods)
12
12
  end
13
13
 
@@ -86,6 +86,15 @@ module ROM
86
86
  end
87
87
  end
88
88
 
89
+ # Lint: Ensure +gateway_instance+ returns adapter name
90
+ def lint_adapter_reader
91
+ if gateway_instance.adapter != identifier
92
+ complain "#{gateway_instance} must have the adapter identifier set to #{identifier.inspect}"
93
+ end
94
+ rescue MissingAdapterIdentifierError
95
+ complain "#{gateway_instance} is missing the adapter identifier"
96
+ end
97
+
89
98
  private
90
99
 
91
100
  # Setup gateway instance
@@ -1,3 +1,5 @@
1
+ require 'dry/core/class_attributes'
2
+
1
3
  module ROM
2
4
  module Plugins
3
5
  module Relation
@@ -6,20 +8,26 @@ module ROM
6
8
  #
7
9
  # @api public
8
10
  module Instrumentation
11
+ extend Dry::Core::ClassAttributes
12
+
9
13
  # This hooks sets up a relation class with injectible notifications object
10
14
  #
11
15
  # @api private
12
16
  def self.included(klass)
13
17
  super
14
- klass.option :notifications, reader: true
18
+ klass.option :notifications
15
19
  klass.extend(ClassInterface)
20
+ klass.prepend(mixin)
16
21
  klass.instrument(:to_a)
17
22
  end
18
23
 
24
+ defines :mixin
25
+ mixin Module.new
26
+
19
27
  module ClassInterface
20
28
  def instrument(*methods)
21
- methods.each do |meth|
22
- define_method(meth) do
29
+ (methods - Instrumentation.mixin.instance_methods).each do |meth|
30
+ Instrumentation.mixin.send(:define_method, meth) do
23
31
  instrument { super() }
24
32
  end
25
33
  end
@@ -28,7 +36,7 @@ module ROM
28
36
 
29
37
  # @api public
30
38
  def instrument(&block)
31
- notifications.instrument(self.class.adapter, { name: name.relation }.merge(notification_payload(self)), &block)
39
+ notifications.instrument(self.class.adapter, name: name.relation, **notification_payload(self), &block)
32
40
  end
33
41
 
34
42
  private
@@ -13,10 +13,7 @@ module ROM
13
13
  def self.included(klass)
14
14
  super
15
15
  return if klass.instance_methods.include?(:__registry__)
16
- klass.option :__registry__,
17
- default: proc { EMPTY_REGISTRY },
18
- reader: true,
19
- optional: true
16
+ klass.option :__registry__, default: -> { EMPTY_REGISTRY }
20
17
  end
21
18
 
22
19
  # @api private
@@ -51,27 +51,25 @@ module ROM
51
51
 
52
52
  # @!attribute [r] mappers
53
53
  # @return [MapperRegistry] an optional mapper registry (empty by default)
54
- option :mappers, reader: true, default: proc { MapperRegistry.new }
54
+ option :mappers, default: -> { MapperRegistry.new }
55
55
 
56
56
  # @!attribute [r] schema
57
57
  # @return [Schema] relation schema, defaults to class-level canonical
58
58
  # schema (if it was defined) and sets an empty one as
59
59
  # the fallback
60
60
  # @api public
61
- option :schema, reader: true, optional: true, default: method(:default_schema).to_proc
61
+ option :schema, default: -> { self.class.default_schema(self) }
62
62
 
63
63
  # @!attribute [r] input_schema
64
64
  # @return [Object#[]] tuple processing function, uses schema or defaults to Hash[]
65
65
  # @api private
66
- option :input_schema, reader: true, default: -> relation {
67
- relation.schema? ? schema.to_input_hash : Hash
68
- }
66
+ option :input_schema, default: -> { schema? ? schema.to_input_hash : Hash }
69
67
 
70
68
  # @!attribute [r] output_schema
71
69
  # @return [Object#[]] tuple processing function, uses schema or defaults to NOOP_OUTPUT_SCHEMA
72
70
  # @api private
73
- option :output_schema, reader: true, optional: true, default: -> relation {
74
- relation.schema.any?(&:read?) ? schema.to_output_hash : NOOP_OUTPUT_SCHEMA
71
+ option :output_schema, default: -> {
72
+ schema.any?(&:read?) ? schema.to_output_hash : NOOP_OUTPUT_SCHEMA
75
73
  }
76
74
 
77
75
  # Return schema attribute
@@ -181,7 +179,15 @@ module ROM
181
179
  #
182
180
  # @api public
183
181
  def new(dataset, new_opts = EMPTY_HASH)
184
- self.class.new(dataset, new_opts.empty? ? options : options.merge(new_opts))
182
+ if new_opts.empty?
183
+ opts = options
184
+ elsif new_opts.key?(:schema)
185
+ opts = options.reject { |k, _| k == :input_schema || k == :output_schema }.merge(new_opts)
186
+ else
187
+ opts = options.merge(new_opts)
188
+ end
189
+
190
+ self.class.new(dataset, opts)
185
191
  end
186
192
 
187
193
  # Returns a new instance with the same dataset but new options
@@ -61,8 +61,7 @@ module ROM
61
61
  # @return [Symbol]
62
62
  #
63
63
  # @api public
64
- option :name, reader: true, optional: true,
65
- default: -> r { Name.new(r.class.register_as, r.class.dataset) }
64
+ option :name, default: -> { Name.new(self.class.register_as, self.class.dataset) }
66
65
  end
67
66
 
68
67
  # Set dataset name
@@ -14,8 +14,8 @@ module ROM
14
14
  param :relation
15
15
 
16
16
  option :name, optional: true, type: Types::Strict::Symbol
17
- option :arity, type: Types::Strict::Int, reader: true, default: proc { -1 }
18
- option :curry_args, reader: true, default: proc { EMPTY_ARRAY }
17
+ option :arity, type: Types::Strict::Int, default: -> { -1 }
18
+ option :curry_args, default: -> { EMPTY_ARRAY }
19
19
 
20
20
  # Relation name
21
21
  #
@@ -23,7 +23,7 @@ module ROM
23
23
  #
24
24
  # @api public
25
25
  def name
26
- @name == Dry::Initializer::UNDEFINED ? relation.name : relation.name.with(@name)
26
+ @name ? relation.name.with(@name) : relation.name
27
27
  end
28
28
 
29
29
  # Load relation if args match the arity
@@ -6,6 +6,8 @@ module ROM
6
6
  #
7
7
  # @api public
8
8
  class Schema
9
+ AttributeAlreadyDefinedError = Class.new(StandardError)
10
+
9
11
  include Dry::Equalizer(:name, :attributes)
10
12
  include Enumerable
11
13
 
@@ -33,7 +35,10 @@ module ROM
33
35
  #
34
36
  # @api public
35
37
  def attribute(name, type, options = EMPTY_HASH)
36
- @attributes ||= {}
38
+ if @attributes.key?(name)
39
+ ::Kernel.raise ::ROM::Schema::AttributeAlreadyDefinedError,
40
+ "Attribute #{ name.inspect } already defined"
41
+ end
37
42
 
38
43
  @attributes[name] =
39
44
  if options[:read]
@@ -14,21 +14,22 @@ module ROM
14
14
 
15
15
  NamespaceType = Types::Strict::Bool | Types::Strict::String
16
16
  PathnameType = Types.Constructor(Pathname, &Kernel.method(:Pathname))
17
+ DEFAULT_MAPPING = {
18
+ relations: :relations,
19
+ mappers: :mappers,
20
+ commands: :commands
21
+ }.freeze
17
22
 
18
23
  param :directory, type: PathnameType
19
24
 
20
- option :namespace, reader: true, type: NamespaceType, default: proc { true }
25
+ option :namespace, type: NamespaceType, default: -> { true }
21
26
 
22
- option :component_dirs, reader: true, type: Types::Strict::Hash, default: proc { {
23
- relations: :relations,
24
- mappers: :mappers,
25
- commands: :commands
26
- } }
27
+ option :component_dirs, type: Types::Strict::Hash, default: -> { DEFAULT_MAPPING }
27
28
 
28
- option :globs, reader: true, default: -> r {
29
+ option :globs, default: -> {
29
30
  Hash[
30
- component_dirs.map { |component, directory|
31
- [component, r.directory.join("#{directory}/**/*.rb")]
31
+ component_dirs.map { |component, path|
32
+ [component, directory.join("#{ path }/**/*.rb")]
32
33
  }
33
34
  ]
34
35
  }
@@ -8,7 +8,7 @@ module ROM
8
8
 
9
9
  PathnameType = Types.Definition(Pathname).constrained(type: Pathname)
10
10
 
11
- option :file, reader: true, type: Types::Strict::String
11
+ option :file, type: Types::Strict::String
12
12
 
13
13
  EXTENSION_REGEX = /\.rb\z/.freeze
14
14
  end
@@ -7,7 +7,7 @@ require 'rom/setup/auto_registration_strategies/base'
7
7
  module ROM
8
8
  module AutoRegistrationStrategies
9
9
  class CustomNamespace < Base
10
- option :namespace, reader: true, type: Types::Strict::String
10
+ option :namespace, type: Types::Strict::String
11
11
 
12
12
  def call
13
13
  "#{namespace}::#{Dry::Core::Inflector.camelize(filename)}"
@@ -7,8 +7,8 @@ require 'rom/setup/auto_registration_strategies/base'
7
7
  module ROM
8
8
  module AutoRegistrationStrategies
9
9
  class NoNamespace < Base
10
- option :directory, reader: true, type: PathnameType
11
- option :entity, reader: true, type: Types::Strict::Symbol
10
+ option :directory, type: PathnameType
11
+ option :entity, type: Types::Strict::Symbol
12
12
 
13
13
  def call
14
14
  Dry::Core::Inflector.camelize(
@@ -6,7 +6,7 @@ require 'rom/setup/auto_registration_strategies/base'
6
6
  module ROM
7
7
  module AutoRegistrationStrategies
8
8
  class WithNamespace < Base
9
- option :directory, reader: true, type: PathnameType
9
+ option :directory, type: PathnameType
10
10
 
11
11
  def call
12
12
  Dry::Core::Inflector.camelize(
@@ -1,3 +1,3 @@
1
1
  module ROM
2
- VERSION = '3.1.0'.freeze
2
+ VERSION = '3.2.0'.freeze
3
3
  end
@@ -19,7 +19,7 @@ Gem::Specification.new do |gem|
19
19
  gem.add_runtime_dependency 'dry-equalizer', '~> 0.2'
20
20
  gem.add_runtime_dependency 'dry-types', '~> 0.9', '>= 0.9.4'
21
21
  gem.add_runtime_dependency 'dry-core', '~> 0.2', '>= 0.2.3'
22
- gem.add_runtime_dependency 'dry-initializer', '~> 0.10', '>= 0.10.2'
22
+ gem.add_runtime_dependency 'dry-initializer', '~> 1.3'
23
23
  gem.add_runtime_dependency 'rom-mapper', '~> 0.5'
24
24
 
25
25
  gem.add_development_dependency 'rake', '~> 10.3'
@@ -1,4 +1,4 @@
1
- if ENV['COVERAGE'] == 'true' && RUBY_ENGINE == 'ruby' && RUBY_VERSION == '2.4.0'
1
+ if ENV['COVERAGE'] == 'true' && RUBY_ENGINE == 'ruby' && RUBY_VERSION == '2.4.1'
2
2
  require "simplecov"
3
3
  SimpleCov.start do
4
4
  add_filter '/spec/'
@@ -47,4 +47,5 @@ RSpec.configure do |config|
47
47
  end
48
48
 
49
49
  config.disable_monkey_patching!
50
+ config.warnings = true
50
51
  end
@@ -48,6 +48,13 @@ RSpec.describe ROM::Commands::Create[:memory], 'before/after hooks' do
48
48
  it 'returns a new command with configured after hooks' do
49
49
  expect(command.after(:prepare).after_hooks).to eql(%i[finalize filter prepare])
50
50
  end
51
+
52
+ it 'worker with before' do
53
+ with_before_and_after = command.before(:filter).after(:finalize)
54
+
55
+ expect(with_before_and_after.before_hooks).to eql(%i[filter])
56
+ expect(with_before_and_after.after_hooks).to eql(%i[finalize filter finalize])
57
+ end
51
58
  end
52
59
 
53
60
  context 'without curried args' do
@@ -19,7 +19,7 @@ RSpec.describe ROM::Memory::Dataset do
19
19
  describe 'subclassing' do
20
20
  it 'supports options' do
21
21
  descendant = Class.new(ROM::Memory::Dataset) do
22
- option :path, reader: true
22
+ option :path
23
23
  end
24
24
 
25
25
  dataset = descendant.new([1, 2, 3], path: '/data')
@@ -12,7 +12,7 @@ RSpec.describe ROM::Memory::Relation do
12
12
  attribute :email, ROM::Types::String
13
13
  attribute :age, ROM::Types::Int
14
14
  end
15
- end.new(dataset)
15
+ end.new(dataset)
16
16
  end
17
17
 
18
18
  let(:dataset) do
@@ -2,6 +2,10 @@ require 'rom'
2
2
  require 'rom/memory'
3
3
 
4
4
  RSpec.describe ROM::Plugins::Relation::Instrumentation do
5
+ before do
6
+ described_class.mixin Module.new
7
+ end
8
+
5
9
  subject(:relation) do
6
10
  relation_class.new(dataset, notifications: notifications)
7
11
  end
@@ -157,5 +157,18 @@ RSpec.describe ROM::Relation, '.schema' do
157
157
 
158
158
  expect(Test::Users.schema[:admin]).to eql(ROM::Types::Bool.meta(name: :admin, source: ROM::Relation::Name[:test_users]))
159
159
  end
160
+
161
+ it 'raises an error on double definition' do
162
+ expect {
163
+ class Test::Users < ROM::Relation[:memory]
164
+ schema do
165
+ attribute :id, Types::Int.meta(primary_key: true)
166
+ attribute :name, Types::String
167
+ attribute :id, Types::Int
168
+ end
169
+ end
170
+ }.to raise_error(ROM::Schema::AttributeAlreadyDefinedError,
171
+ /:id already defined/)
172
+ end
160
173
  end
161
174
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rom
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.1.0
4
+ version: 3.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-03-01 00:00:00.000000000 Z
11
+ date: 2017-03-25 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: concurrent-ruby
@@ -84,20 +84,14 @@ dependencies:
84
84
  requirements:
85
85
  - - "~>"
86
86
  - !ruby/object:Gem::Version
87
- version: '0.10'
88
- - - ">="
89
- - !ruby/object:Gem::Version
90
- version: 0.10.2
87
+ version: '1.3'
91
88
  type: :runtime
92
89
  prerelease: false
93
90
  version_requirements: !ruby/object:Gem::Requirement
94
91
  requirements:
95
92
  - - "~>"
96
93
  - !ruby/object:Gem::Version
97
- version: '0.10'
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- version: 0.10.2
94
+ version: '1.3'
101
95
  - !ruby/object:Gem::Dependency
102
96
  name: rom-mapper
103
97
  requirement: !ruby/object:Gem::Requirement
@@ -400,7 +394,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
400
394
  version: '0'
401
395
  requirements: []
402
396
  rubyforge_project:
403
- rubygems_version: 2.6.9
397
+ rubygems_version: 2.6.10
404
398
  signing_key:
405
399
  specification_version: 4
406
400
  summary: Ruby Object Mapper