rom 3.1.0 → 3.2.0

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: 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