Class: ArchSpec::Rules::MustImplementOneOfRule

Inherits:
Object
  • Object
show all
Defined in:
lib/archspec/rules/protocol_rules.rb

Overview

Backs ArchSpec::DSL::ComponentProxy#must_implement_one_of. Flags classes that implement none of the named methods.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(source, method_names, scope: :instance) ⇒ MustImplementOneOfRule

Returns a new instance of MustImplementOneOfRule.

Raises:



185
186
187
188
189
190
191
192
193
# File 'lib/archspec/rules/protocol_rules.rb', line 185

def initialize(source, method_names, scope: :instance)
  ProtocolEvidence.validate_scope!(scope, for_rule: 'must_implement_one_of')
  @source = source.to_sym
  names = Array(method_names).flatten.compact
  raise Error, 'must_implement_one_of requires at least one method' if names.empty?

  @method_names = names.map(&:to_sym)
  @scope = scope
end

Instance Attribute Details

#method_namesObject (readonly)

Returns the value of attribute method_names.



183
184
185
# File 'lib/archspec/rules/protocol_rules.rb', line 183

def method_names
  @method_names
end

#scopeObject (readonly)

Returns the value of attribute scope.



183
184
185
# File 'lib/archspec/rules/protocol_rules.rb', line 183

def scope
  @scope
end

#sourceObject (readonly)

Returns the value of attribute source.



183
184
185
# File 'lib/archspec/rules/protocol_rules.rb', line 183

def source
  @source
end

Instance Method Details

#evaluate(graph) ⇒ Object



208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
# File 'lib/archspec/rules/protocol_rules.rb', line 208

def evaluate(graph)
  constants_for(graph).filter_map do |constant|
    methods, unresolved =
      if scope == :class
        graph.effective_class_methods(constant.name)
      else
        graph.effective_instance_methods(constant.name)
      end
    next if method_names.any? { |method_name| methods.include?(method_name) }

    sigil = scope == :class ? '.' : '#'
    choices = method_names.map { |name| "#{sigil}#{name}" }.join(', ')
    Diagnostic.new(
      rule: id,
      message: "#{constant.name} must implement one of #{choices}",
      location: constant.location,
      evidence: ProtocolEvidence.for(constant, methods, unresolved, scope: scope),
      confidence: unresolved.empty? ? :high : :medium
    )
  end
end

#idObject



204
205
206
# File 'lib/archspec/rules/protocol_rules.rb', line 204

def id
  'protocol.must_implement_one_of'
end

#merge!(other) ⇒ Object



199
200
201
202
# File 'lib/archspec/rules/protocol_rules.rb', line 199

def merge!(other)
  @method_names |= other.method_names
  self
end

#merge_keyObject



195
196
197
# File 'lib/archspec/rules/protocol_rules.rb', line 195

def merge_key
  [self.class, source, scope]
end