rom-core 4.0.0.beta1
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 +7 -0
- data/CHANGELOG.md +603 -0
- data/LICENSE +20 -0
- data/README.md +18 -0
- data/lib/rom-core.rb +1 -0
- data/lib/rom/array_dataset.rb +44 -0
- data/lib/rom/association_set.rb +16 -0
- data/lib/rom/associations/abstract.rb +135 -0
- data/lib/rom/associations/definitions.rb +5 -0
- data/lib/rom/associations/definitions/abstract.rb +116 -0
- data/lib/rom/associations/definitions/many_to_many.rb +24 -0
- data/lib/rom/associations/definitions/many_to_one.rb +11 -0
- data/lib/rom/associations/definitions/one_to_many.rb +11 -0
- data/lib/rom/associations/definitions/one_to_one.rb +11 -0
- data/lib/rom/associations/definitions/one_to_one_through.rb +11 -0
- data/lib/rom/associations/many_to_many.rb +81 -0
- data/lib/rom/associations/many_to_one.rb +37 -0
- data/lib/rom/associations/one_to_many.rb +37 -0
- data/lib/rom/associations/one_to_one.rb +8 -0
- data/lib/rom/associations/one_to_one_through.rb +8 -0
- data/lib/rom/associations/through_identifier.rb +39 -0
- data/lib/rom/auto_curry.rb +55 -0
- data/lib/rom/cache.rb +46 -0
- data/lib/rom/command.rb +488 -0
- data/lib/rom/command_compiler.rb +239 -0
- data/lib/rom/command_proxy.rb +24 -0
- data/lib/rom/command_registry.rb +141 -0
- data/lib/rom/commands.rb +3 -0
- data/lib/rom/commands/class_interface.rb +270 -0
- data/lib/rom/commands/composite.rb +53 -0
- data/lib/rom/commands/create.rb +13 -0
- data/lib/rom/commands/delete.rb +14 -0
- data/lib/rom/commands/graph.rb +88 -0
- data/lib/rom/commands/graph/class_interface.rb +62 -0
- data/lib/rom/commands/graph/input_evaluator.rb +62 -0
- data/lib/rom/commands/lazy.rb +99 -0
- data/lib/rom/commands/lazy/create.rb +23 -0
- data/lib/rom/commands/lazy/delete.rb +27 -0
- data/lib/rom/commands/lazy/update.rb +34 -0
- data/lib/rom/commands/result.rb +96 -0
- data/lib/rom/commands/update.rb +14 -0
- data/lib/rom/configuration.rb +114 -0
- data/lib/rom/configuration_dsl.rb +87 -0
- data/lib/rom/configuration_dsl/command.rb +41 -0
- data/lib/rom/configuration_dsl/command_dsl.rb +35 -0
- data/lib/rom/configuration_dsl/relation.rb +26 -0
- data/lib/rom/configuration_plugin.rb +17 -0
- data/lib/rom/constants.rb +64 -0
- data/lib/rom/container.rb +147 -0
- data/lib/rom/core.rb +46 -0
- data/lib/rom/create_container.rb +60 -0
- data/lib/rom/data_proxy.rb +94 -0
- data/lib/rom/enumerable_dataset.rb +68 -0
- data/lib/rom/environment.rb +70 -0
- data/lib/rom/gateway.rb +184 -0
- data/lib/rom/global.rb +58 -0
- data/lib/rom/global/plugin_dsl.rb +47 -0
- data/lib/rom/initializer.rb +64 -0
- data/lib/rom/lint/enumerable_dataset.rb +54 -0
- data/lib/rom/lint/gateway.rb +120 -0
- data/lib/rom/lint/linter.rb +78 -0
- data/lib/rom/lint/spec.rb +20 -0
- data/lib/rom/lint/test.rb +98 -0
- data/lib/rom/mapper_registry.rb +24 -0
- data/lib/rom/memory.rb +4 -0
- data/lib/rom/memory/associations.rb +4 -0
- data/lib/rom/memory/associations/many_to_many.rb +10 -0
- data/lib/rom/memory/associations/many_to_one.rb +10 -0
- data/lib/rom/memory/associations/one_to_many.rb +10 -0
- data/lib/rom/memory/associations/one_to_one.rb +10 -0
- data/lib/rom/memory/commands.rb +56 -0
- data/lib/rom/memory/dataset.rb +97 -0
- data/lib/rom/memory/gateway.rb +64 -0
- data/lib/rom/memory/relation.rb +62 -0
- data/lib/rom/memory/schema.rb +23 -0
- data/lib/rom/memory/storage.rb +59 -0
- data/lib/rom/memory/types.rb +9 -0
- data/lib/rom/pipeline.rb +105 -0
- data/lib/rom/plugin.rb +25 -0
- data/lib/rom/plugin_base.rb +45 -0
- data/lib/rom/plugin_registry.rb +197 -0
- data/lib/rom/plugins/command/schema.rb +37 -0
- data/lib/rom/plugins/configuration/configuration_dsl.rb +21 -0
- data/lib/rom/plugins/relation/instrumentation.rb +51 -0
- data/lib/rom/plugins/relation/registry_reader.rb +44 -0
- data/lib/rom/plugins/schema/timestamps.rb +58 -0
- data/lib/rom/registry.rb +71 -0
- data/lib/rom/relation.rb +548 -0
- data/lib/rom/relation/class_interface.rb +282 -0
- data/lib/rom/relation/commands.rb +23 -0
- data/lib/rom/relation/composite.rb +46 -0
- data/lib/rom/relation/curried.rb +103 -0
- data/lib/rom/relation/graph.rb +197 -0
- data/lib/rom/relation/loaded.rb +127 -0
- data/lib/rom/relation/materializable.rb +66 -0
- data/lib/rom/relation/name.rb +111 -0
- data/lib/rom/relation/view_dsl.rb +64 -0
- data/lib/rom/relation/wrap.rb +83 -0
- data/lib/rom/relation_registry.rb +10 -0
- data/lib/rom/schema.rb +437 -0
- data/lib/rom/schema/associations_dsl.rb +195 -0
- data/lib/rom/schema/attribute.rb +419 -0
- data/lib/rom/schema/dsl.rb +164 -0
- data/lib/rom/schema/inferrer.rb +66 -0
- data/lib/rom/schema_plugin.rb +27 -0
- data/lib/rom/setup.rb +68 -0
- data/lib/rom/setup/auto_registration.rb +74 -0
- data/lib/rom/setup/auto_registration_strategies/base.rb +16 -0
- data/lib/rom/setup/auto_registration_strategies/custom_namespace.rb +63 -0
- data/lib/rom/setup/auto_registration_strategies/no_namespace.rb +20 -0
- data/lib/rom/setup/auto_registration_strategies/with_namespace.rb +18 -0
- data/lib/rom/setup/finalize.rb +103 -0
- data/lib/rom/setup/finalize/finalize_commands.rb +60 -0
- data/lib/rom/setup/finalize/finalize_mappers.rb +56 -0
- data/lib/rom/setup/finalize/finalize_relations.rb +135 -0
- data/lib/rom/support/configurable.rb +85 -0
- data/lib/rom/support/memoizable.rb +58 -0
- data/lib/rom/support/notifications.rb +103 -0
- data/lib/rom/transaction.rb +24 -0
- data/lib/rom/types.rb +26 -0
- data/lib/rom/version.rb +5 -0
- metadata +289 -0
@@ -0,0 +1,70 @@
|
|
1
|
+
require 'rom/support/configurable'
|
2
|
+
require 'rom/gateway'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
# Core gateway configuration interface
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
class Environment
|
9
|
+
include Configurable
|
10
|
+
|
11
|
+
attr_reader :gateways, :gateways_map
|
12
|
+
|
13
|
+
# @api public
|
14
|
+
def initialize(*args)
|
15
|
+
@gateways = {}
|
16
|
+
@gateways_map = {}
|
17
|
+
|
18
|
+
configure_gateways(*args) unless args.empty?
|
19
|
+
end
|
20
|
+
|
21
|
+
private
|
22
|
+
|
23
|
+
def configure_gateways(*args)
|
24
|
+
normalized_gateway_args = normalize_gateway_args(*args)
|
25
|
+
normalized_gateways = normalize_gateways(normalized_gateway_args)
|
26
|
+
|
27
|
+
@gateways, @gateways_map = normalized_gateways.values_at(:gateways, :map)
|
28
|
+
|
29
|
+
normalized_gateway_args.each_with_object(config) do |(name, gateway_config), config|
|
30
|
+
options = gateway_config.is_a?(Array) && gateway_config.last
|
31
|
+
load_config(config.gateways[name], options) if options.is_a?(Hash)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
# @api private
|
37
|
+
def normalize_gateway_args(*args)
|
38
|
+
args.first.is_a?(Hash) ? args.first : { default: args }
|
39
|
+
end
|
40
|
+
|
41
|
+
# Build gateways using the setup interface
|
42
|
+
#
|
43
|
+
# @api private
|
44
|
+
def normalize_gateways(gateways_config)
|
45
|
+
gateways_config.each_with_object(map: {}, gateways: {}) do |(name, spec), hash|
|
46
|
+
identifier, *args = Array(spec)
|
47
|
+
|
48
|
+
if identifier.is_a?(Gateway)
|
49
|
+
gateway = identifier
|
50
|
+
else
|
51
|
+
gateway = Gateway.setup(identifier, *args.flatten)
|
52
|
+
end
|
53
|
+
|
54
|
+
hash[:map][gateway] = name
|
55
|
+
hash[:gateways][name] = gateway
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# @api private
|
60
|
+
def load_config(config, hash)
|
61
|
+
hash.each do |key, value|
|
62
|
+
if value.is_a?(Hash)
|
63
|
+
load_config(config[key], value)
|
64
|
+
else
|
65
|
+
config.send("#{key}=", value)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
data/lib/rom/gateway.rb
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
require 'dry/core/class_attributes'
|
2
|
+
|
3
|
+
require 'rom/transaction'
|
4
|
+
require 'rom/support/notifications'
|
5
|
+
|
6
|
+
module ROM
|
7
|
+
# Abstract gateway class
|
8
|
+
#
|
9
|
+
# Every adapter needs to inherit from this class and implement
|
10
|
+
# required interface
|
11
|
+
#
|
12
|
+
# @abstract
|
13
|
+
#
|
14
|
+
# @api public
|
15
|
+
class Gateway
|
16
|
+
extend Dry::Core::ClassAttributes
|
17
|
+
extend Notifications::Listener
|
18
|
+
|
19
|
+
defines :adapter
|
20
|
+
|
21
|
+
# @!attribute [r] connection
|
22
|
+
# @return [Object] The gateway's connection object (type varies across adapters)
|
23
|
+
attr_reader :connection
|
24
|
+
|
25
|
+
# Set up a gateway
|
26
|
+
#
|
27
|
+
# @overload setup(type, *args)
|
28
|
+
# Sets up a single-gateway given a gateway type.
|
29
|
+
# For custom gateways, create an instance and pass it directly.
|
30
|
+
#
|
31
|
+
# @example
|
32
|
+
# module SuperDB
|
33
|
+
# class Gateway < ROM::Gateway
|
34
|
+
# def initialize(options)
|
35
|
+
# end
|
36
|
+
# end
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# ROM.register_adapter(:super_db, SuperDB)
|
40
|
+
#
|
41
|
+
# Gateway.setup(:super_db, some: 'options')
|
42
|
+
# # SuperDB::Gateway.new(some: 'options') is called
|
43
|
+
#
|
44
|
+
# @param [Symbol] type Registered gateway identifier
|
45
|
+
# @param [Array] args Additional gateway options
|
46
|
+
#
|
47
|
+
# @overload setup(gateway)
|
48
|
+
# Set up a gateway instance
|
49
|
+
#
|
50
|
+
# @example
|
51
|
+
# module SuperDB
|
52
|
+
# class Gateway < ROM::Gateway
|
53
|
+
# def initialize(options)
|
54
|
+
# end
|
55
|
+
# end
|
56
|
+
# end
|
57
|
+
#
|
58
|
+
# ROM.register_adapter(:super_db, SuperDB)
|
59
|
+
#
|
60
|
+
# Gateway.setup(SuperDB::Gateway.new(some: 'options'))
|
61
|
+
#
|
62
|
+
# @param [Gateway] gateway
|
63
|
+
#
|
64
|
+
# @return [Gateway] a specific gateway subclass
|
65
|
+
#
|
66
|
+
# @api public
|
67
|
+
def self.setup(gateway_or_scheme, *args)
|
68
|
+
case gateway_or_scheme
|
69
|
+
when String
|
70
|
+
raise ArgumentError, <<-STRING.gsub(/^ {10}/, '')
|
71
|
+
URIs without an explicit scheme are not supported anymore.
|
72
|
+
See https://github.com/rom-rb/rom/blob/master/CHANGELOG.md
|
73
|
+
STRING
|
74
|
+
when Symbol
|
75
|
+
klass = class_from_symbol(gateway_or_scheme)
|
76
|
+
|
77
|
+
if klass.instance_method(:initialize).arity == 0
|
78
|
+
klass.new
|
79
|
+
else
|
80
|
+
klass.new(*args)
|
81
|
+
end
|
82
|
+
else
|
83
|
+
if args.empty?
|
84
|
+
gateway_or_scheme
|
85
|
+
else
|
86
|
+
raise ArgumentError, "Can't accept arguments when passing an instance"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
# Get gateway subclass for a specific adapter
|
92
|
+
#
|
93
|
+
# @param [Symbol] type Adapter identifier
|
94
|
+
#
|
95
|
+
# @return [Class]
|
96
|
+
#
|
97
|
+
# @api private
|
98
|
+
def self.class_from_symbol(type)
|
99
|
+
adapter = ROM.adapters.fetch(type) {
|
100
|
+
begin
|
101
|
+
require "rom/#{type}"
|
102
|
+
rescue LoadError
|
103
|
+
raise AdapterLoadError, "Failed to load adapter rom/#{type}"
|
104
|
+
end
|
105
|
+
|
106
|
+
ROM.adapters.fetch(type)
|
107
|
+
}
|
108
|
+
|
109
|
+
adapter.const_get(:Gateway)
|
110
|
+
end
|
111
|
+
|
112
|
+
# Returns the adapter, defined for the class
|
113
|
+
#
|
114
|
+
# @return [Symbol]
|
115
|
+
#
|
116
|
+
# @api public
|
117
|
+
def adapter
|
118
|
+
self.class.adapter || raise(
|
119
|
+
MissingAdapterIdentifierError,
|
120
|
+
"gateway class +#{self}+ is missing the adapter identifier"
|
121
|
+
)
|
122
|
+
end
|
123
|
+
|
124
|
+
# A generic interface for setting up a logger
|
125
|
+
#
|
126
|
+
# This is not a required interface, it's a no-op by default
|
127
|
+
#
|
128
|
+
# @abstract
|
129
|
+
#
|
130
|
+
# @api public
|
131
|
+
def use_logger(*)
|
132
|
+
# noop
|
133
|
+
end
|
134
|
+
|
135
|
+
# A generic interface for returning default logger
|
136
|
+
#
|
137
|
+
# Adapters should implement this method as handling loggers is different
|
138
|
+
# across adapters. This is a no-op by default and returns nil.
|
139
|
+
#
|
140
|
+
# @return [NilClass]
|
141
|
+
#
|
142
|
+
# @api public
|
143
|
+
def logger
|
144
|
+
# noop
|
145
|
+
end
|
146
|
+
|
147
|
+
# Schema inference hook
|
148
|
+
#
|
149
|
+
# Every gateway that supports schema inference should implement this method
|
150
|
+
#
|
151
|
+
# @return [Array] An array with dataset names
|
152
|
+
#
|
153
|
+
# @api private
|
154
|
+
def schema
|
155
|
+
[]
|
156
|
+
end
|
157
|
+
|
158
|
+
# Disconnect is optional and it's a no-op by default
|
159
|
+
#
|
160
|
+
# @api public
|
161
|
+
def disconnect
|
162
|
+
# noop
|
163
|
+
end
|
164
|
+
|
165
|
+
# Runs a block inside a transaction. The underlying transaction engine
|
166
|
+
# is adapter-specific
|
167
|
+
#
|
168
|
+
# @param [Hash] Transaction options
|
169
|
+
# @return The result of yielding the block or +nil+ if
|
170
|
+
# the transaction was rolled back
|
171
|
+
#
|
172
|
+
# @api public
|
173
|
+
def transaction(opts = EMPTY_HASH, &block)
|
174
|
+
transaction_runner(opts).run(opts, &block)
|
175
|
+
end
|
176
|
+
|
177
|
+
private
|
178
|
+
|
179
|
+
# @api private
|
180
|
+
def transaction_runner(_)
|
181
|
+
Transaction::NoOp
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
data/lib/rom/global.rb
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rom/plugin_registry'
|
2
|
+
require 'rom/global/plugin_dsl'
|
3
|
+
|
4
|
+
module ROM
|
5
|
+
# Globally accessible public interface exposed via ROM module
|
6
|
+
#
|
7
|
+
# @api public
|
8
|
+
module Global
|
9
|
+
# Set base global registries in ROM constant
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
def self.extended(rom)
|
13
|
+
super
|
14
|
+
|
15
|
+
rom.instance_variable_set('@adapters', {})
|
16
|
+
rom.instance_variable_set('@plugin_registry', PluginRegistry.new)
|
17
|
+
end
|
18
|
+
|
19
|
+
# An internal adapter identifier => adapter module map used by setup
|
20
|
+
#
|
21
|
+
# @return [Hash<Symbol=>Module>]
|
22
|
+
#
|
23
|
+
# @api private
|
24
|
+
attr_reader :adapters
|
25
|
+
|
26
|
+
# An internal identifier => plugin map used by the setup
|
27
|
+
#
|
28
|
+
# @return [Hash]
|
29
|
+
#
|
30
|
+
# @api private
|
31
|
+
attr_reader :plugin_registry
|
32
|
+
|
33
|
+
# Global plugin setup DSL
|
34
|
+
#
|
35
|
+
# @example
|
36
|
+
# ROM.plugins do
|
37
|
+
# register :publisher, Plugin::Publisher, type: :command
|
38
|
+
# end
|
39
|
+
#
|
40
|
+
# @example
|
41
|
+
def plugins(*args, &block)
|
42
|
+
PluginDSL.new(plugin_registry, *args, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
# Register adapter namespace under a specified identifier
|
46
|
+
#
|
47
|
+
# @param [Symbol] identifier
|
48
|
+
# @param [Class,Module] adapter
|
49
|
+
#
|
50
|
+
# @return [self]
|
51
|
+
#
|
52
|
+
# @api private
|
53
|
+
def register_adapter(identifier, adapter)
|
54
|
+
adapters[identifier] = adapter
|
55
|
+
self
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
module ROM
|
2
|
+
module Global
|
3
|
+
# plugin registration DSL
|
4
|
+
#
|
5
|
+
# @private
|
6
|
+
class PluginDSL
|
7
|
+
# Default options passed to plugin registration
|
8
|
+
#
|
9
|
+
# @return [Hash]
|
10
|
+
#
|
11
|
+
# @api private
|
12
|
+
attr_reader :defaults
|
13
|
+
|
14
|
+
# Plugin registry
|
15
|
+
#
|
16
|
+
# @return [PluginRegistry]
|
17
|
+
#
|
18
|
+
# @api private
|
19
|
+
attr_reader :registry
|
20
|
+
|
21
|
+
# @api private
|
22
|
+
def initialize(registry, defaults = EMPTY_HASH, &block)
|
23
|
+
@registry = registry
|
24
|
+
@defaults = defaults
|
25
|
+
instance_exec(&block)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Register a plugin
|
29
|
+
#
|
30
|
+
# @param [Symbol] name of the plugin
|
31
|
+
# @param [Module] mod to include
|
32
|
+
# @param [Hash] options
|
33
|
+
#
|
34
|
+
# @api public
|
35
|
+
def register(name, mod, options = EMPTY_HASH)
|
36
|
+
registry.register(name, mod, defaults.merge(options))
|
37
|
+
end
|
38
|
+
|
39
|
+
# Register plugins for a specific adapter
|
40
|
+
#
|
41
|
+
# @param [Symbol] adapter type
|
42
|
+
def adapter(type, &block)
|
43
|
+
self.class.new(registry, adapter: type, &block)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'dry-initializer'
|
2
|
+
|
3
|
+
module ROM
|
4
|
+
|
5
|
+
# @api private
|
6
|
+
module Initializer
|
7
|
+
# @api private
|
8
|
+
module DefineWithHook
|
9
|
+
def param(*)
|
10
|
+
super
|
11
|
+
|
12
|
+
__define_with__
|
13
|
+
end
|
14
|
+
|
15
|
+
def option(*)
|
16
|
+
super
|
17
|
+
|
18
|
+
__define_with__ unless method_defined?(:with)
|
19
|
+
end
|
20
|
+
|
21
|
+
def __define_with__
|
22
|
+
seq_names = __initializer_mixin__.
|
23
|
+
instance_method(:__initialize__).
|
24
|
+
parameters.
|
25
|
+
select { |type, _| type == :req }.
|
26
|
+
map { |_, name| name }.
|
27
|
+
join(', ')
|
28
|
+
|
29
|
+
seq_names << ', ' unless seq_names.empty?
|
30
|
+
|
31
|
+
undef_method(:with) if method_defined?(:with)
|
32
|
+
|
33
|
+
class_eval(<<-RUBY, __FILE__, __LINE__ + 1)
|
34
|
+
def with(new_options = EMPTY_HASH)
|
35
|
+
if new_options.empty?
|
36
|
+
self
|
37
|
+
else
|
38
|
+
self.class.new(#{ seq_names }options.merge(new_options))
|
39
|
+
end
|
40
|
+
end
|
41
|
+
RUBY
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @api private
|
46
|
+
def self.extended(base)
|
47
|
+
base.extend(Dry::Initializer[undefined: false])
|
48
|
+
base.extend(DefineWithHook)
|
49
|
+
base.include(InstanceMethods)
|
50
|
+
end
|
51
|
+
|
52
|
+
# @api private
|
53
|
+
module InstanceMethods
|
54
|
+
# Instance options
|
55
|
+
#
|
56
|
+
# @return [Hash]
|
57
|
+
#
|
58
|
+
# @api public
|
59
|
+
def options
|
60
|
+
@__options__
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'rom/lint/linter'
|
2
|
+
|
3
|
+
module ROM
|
4
|
+
module Lint
|
5
|
+
# Ensures that a [ROM::EnumerableDataset] extension correctly yields
|
6
|
+
# arrays and tuples
|
7
|
+
#
|
8
|
+
# @api public
|
9
|
+
class EnumerableDataset < ROM::Lint::Linter
|
10
|
+
# The linted subject
|
11
|
+
#
|
12
|
+
# @api public
|
13
|
+
attr_reader :dataset
|
14
|
+
|
15
|
+
# The expected data
|
16
|
+
#
|
17
|
+
# @api public
|
18
|
+
attr_reader :data
|
19
|
+
|
20
|
+
# Create a linter for EnumerableDataset
|
21
|
+
#
|
22
|
+
# @param [EnumerableDataset] dataset the linted subject
|
23
|
+
# @param [Object] data the expected data
|
24
|
+
#
|
25
|
+
# @api public
|
26
|
+
def initialize(dataset, data)
|
27
|
+
@dataset = dataset
|
28
|
+
@data = data
|
29
|
+
end
|
30
|
+
|
31
|
+
# Lint: Ensure that +dataset+ yield tuples via +each+
|
32
|
+
#
|
33
|
+
# @api public
|
34
|
+
def lint_each
|
35
|
+
result = []
|
36
|
+
dataset.each do |tuple|
|
37
|
+
result << tuple
|
38
|
+
end
|
39
|
+
return if result == data
|
40
|
+
|
41
|
+
complain "#{dataset.class}#each must yield tuples"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Lint: Ensure that +dataset+'s array equals to expected +data+
|
45
|
+
#
|
46
|
+
# @api public
|
47
|
+
def lint_to_a
|
48
|
+
return if dataset.to_a == data
|
49
|
+
|
50
|
+
complain "#{dataset.class}#to_a must cast dataset to an array"
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|