Class: Mxrb::Evaluation::Suite

Inherits:
Object
  • Object
show all
Defined in:
lib/mxrb/evaluation.rb

Overview

Defines executable expectations for a Mendix model using Ruby only.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(project) ⇒ Suite

Returns a new instance of Suite.



27
28
29
30
# File 'lib/mxrb/evaluation.rb', line 27

def initialize(project)
  @project = project
  @checks = []
end

Instance Attribute Details

#checksObject (readonly)

Returns the value of attribute checks.



25
26
27
# File 'lib/mxrb/evaluation.rb', line 25

def checks
  @checks
end

#projectObject (readonly)

Returns the value of attribute project.



25
26
27
# File 'lib/mxrb/evaluation.rb', line 25

def project
  @project
end

Instance Method Details

#artifact(name, kind: nil, severity: :error) ⇒ Object



42
43
44
45
46
47
# File 'lib/mxrb/evaluation.rb', line 42

def artifact(name, kind: nil, severity: :error)
  check("artifact #{name} exists", severity:) do
    found = project.find_artifact(name, kind:)
    found ? true : "missing #{kind || 'artifact'} #{name}"
  end
end

#check(name, severity: :error, &block) ⇒ Object

Raises:

  • (ArgumentError)


32
33
34
35
36
37
38
39
40
# File 'lib/mxrb/evaluation.rb', line 32

def check(name, severity: :error, &block)
  raise ArgumentError, "evaluation check requires a block" unless block
  unless %i[error warning].include?(severity.to_sym)
    raise ArgumentError, "evaluation severity must be :error or :warning"
  end

  @checks << Check.new(name.to_s, severity.to_sym, block)
  self
end

#evaluate(path) ⇒ Object



101
102
103
104
# File 'lib/mxrb/evaluation.rb', line 101

def evaluate(path)
  instance_eval(File.read(path), path, 1)
  self
end

#forbid_dependency(from:, to:, severity: :error) ⇒ Object



83
84
85
86
87
88
89
90
# File 'lib/mxrb/evaluation.rb', line 83

def forbid_dependency(from:, to:, severity: :error)
  check("#{from} does not depend on #{to}", severity:) do
    dependency = project.analyze.module_dependencies.find do
      _1.from == from.to_s && _1.to == to.to_s
    end
    dependency ? "#{dependency.references.size} forbidden reference(s)" : true
  end
end

#maximum_unreferenced(count, severity: :warning) ⇒ Object



76
77
78
79
80
81
# File 'lib/mxrb/evaluation.rb', line 76

def maximum_unreferenced(count, severity: :warning)
  check("model has at most #{count} unreferenced artifacts", severity:) do
    actual = project.analyze.unreferenced.size
    actual <= count ? true : "#{actual} unreferenced artifacts exceed maximum #{count}"
  end
end

#no_call_cycles(severity: :error) ⇒ Object



62
63
64
65
66
67
# File 'lib/mxrb/evaluation.rb', line 62

def no_call_cycles(severity: :error)
  check("model has no call cycles", severity:) do
    cycles = project.analyze.call_cycles
    cycles.empty? ? true : "#{cycles.size} call cycle(s) found"
  end
end

#no_missing_internal_references(severity: :error) ⇒ Object



69
70
71
72
73
74
# File 'lib/mxrb/evaluation.rb', line 69

def no_missing_internal_references(severity: :error)
  check("model has no missing internal references", severity:) do
    missing = project.analyze.errors.select { _1.rule == :unresolved_reference }
    missing.empty? ? true : "#{missing.size} internal reference(s) missing"
  end
end

#reference(from:, to:, relation: nil, severity: :error) ⇒ Object



49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/mxrb/evaluation.rb', line 49

def reference(from:, to:, relation: nil, severity: :error)
  check("#{from} references #{to}", severity:) do
    source = project.find_artifact(from)
    target = project.find_artifact(to)
    next "missing source #{from}" unless source
    next "missing target #{to}" unless target

    matches = project.references_from(source).select { _1.target.id == target.id }
    matches = matches.select { _1.relation == relation.to_sym } if relation
    matches.empty? ? "reference #{from} -> #{to} not found" : true
  end
end

#require_dependency(from:, to:, severity: :error) ⇒ Object



92
93
94
95
96
97
98
99
# File 'lib/mxrb/evaluation.rb', line 92

def require_dependency(from:, to:, severity: :error)
  check("#{from} depends on #{to}", severity:) do
    dependency = project.analyze.module_dependencies.find do
      _1.from == from.to_s && _1.to == to.to_s
    end
    dependency ? true : "required module dependency not found"
  end
end

#runObject



106
107
108
# File 'lib/mxrb/evaluation.rb', line 106

def run
  Result.new(@checks.map { execute(_1) }.freeze)
end