Module: AsyncapiCable::Generator::DeclarationLoader

Defined in:
lib/asyncapi_cable/generator/declaration_loader.rb

Overview

Loads the spec/test files that carry channel declarations so the MetadataStore holds them. Both the generator and the channel-coverage gate need exactly that, in whichever framework the host writes its declarations.

Loading must not run the files. Both suppressors come from openapi-ruby rather than being reimplemented here: they work around another library's at_exit and schema-check behaviour, and two copies of that would drift.

Constant Summary collapse

FRAMEWORKS =
%w[rspec minitest hybrid].freeze

Class Method Summary collapse

Class Method Details

.announce_declaration_run!Object

Announced through the environment so a host test helper guarding on either flag skips its test-time setup. In-process callers (the channel-coverage gate) need this as much as the generation subprocess, and it is not restored afterwards: the files loaded under the guard stay loaded, so pretending the run is over would be a lie.



44
45
46
47
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 44

def announce_declaration_run!
  ENV["ASYNCAPI_CABLE_GENERATING"] ||= "true"
  ENV["OPENAPI_RUBY_GENERATING"] ||= "true"
end

.globs_for(pattern) ⇒ Object

Each glob is loaded with its own framework directory at the head of $LOAD_PATH, so the require "rails_helper" / require "test_helper" at the top of a declaration file resolves to the right helper. Spec globs load before test globs, matching openapi-ruby's hybrid script.



62
63
64
65
66
67
68
69
70
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 62

def globs_for(pattern)
  globs = pattern.to_s.split(",").map(&:strip).reject(&:empty?)
  spec_globs = globs.grep(%r{\bspec/})
  test_globs = globs.grep(%r{\btest/})

  spec_globs.map { |glob| ["spec", glob] } +
    test_globs.map { |glob| ["test", glob] } +
    (globs - spec_globs - test_globs).map { |glob| [nil, glob] }
end

.install_adapters!(framework) ⇒ Object

The adapter has to be live before a declaration file loads — its class body is what calls the DSL.



23
24
25
26
27
28
29
30
31
32
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 23

def install_adapters!(framework)
  validate_framework!(framework)

  if framework != "minitest"
    require "rspec/core"
    require "asyncapi_cable/rspec"
  end

  require "asyncapi_cable/minitest" if framework != "rspec"
end

.load!(framework:, pattern:) ⇒ Object

Returns the files that were loaded, in load order.



50
51
52
53
54
55
56
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 50

def load!(framework:, pattern:)
  install_adapters!(framework)
  announce_declaration_run!
  suppress_side_effects!

  globs_for(pattern).flat_map { |dir, glob| load_glob(dir, glob) }
end

.load_glob(dir, glob) ⇒ Object



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 72

def load_glob(dir, glob)
  # A glob can legitimately resolve directories (`test/asyncapi/**`);
  # `require` on one raises LoadError.
  files = Dir.glob(glob).select { |file| File.file?(file) }.sort
  return [] if files.empty?
  return files.each { |file| require File.expand_path(file) } if dir.nil?

  path = File.expand_path(dir)
  added = !$LOAD_PATH.include?(path)
  $LOAD_PATH.unshift(path) if added
  begin
    files.each { |file| require File.expand_path(file) }
  ensure
    $LOAD_PATH.delete(path) if added
  end
end

.suppress_side_effects!Object



34
35
36
37
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 34

def suppress_side_effects!
  OpenapiRuby::Generator::AutorunSuppressor.install!
  OpenapiRuby::Generator::TestSchemaSuppressor.install!
end

.validate_framework!(framework) ⇒ Object

Raises:

  • (ArgumentError)


89
90
91
92
93
94
# File 'lib/asyncapi_cable/generator/declaration_loader.rb', line 89

def validate_framework!(framework)
  return if FRAMEWORKS.include?(framework)

  raise ArgumentError,
    "Unknown test framework #{framework.inspect}. Expected one of #{FRAMEWORKS.join(", ")}."
end