require_relative '../test_helper' require 'open3' # in a fresh process: plugins and their gems are loaded only when used class LazyLoadingTest < PipelineTest def loaded_after code script = <<~RUBY require 'bundler/setup' require #{File.join(ROOT, 'lib/datapipeline').inspect} #{code} features = $LOADED_FEATURES.join(' ') puts %w[pg sqlite3 roo caxlsx http].select { |gem| features.match?(%r{/gems/\#{gem}-\\d}) }.join(',') RUBY out, err, status = Open3.capture3({ 'BUNDLE_GEMFILE' => File.join(ROOT, 'Gemfile') }, RbConfig.ruby, '-e', script) assert status.success?, err out.strip.split(',') end def test_nothing_loaded_at_start assert_empty loaded_after('') end def test_json_and_csv_need_no_gem with_tmpdir do |dir| code = "DataPipeline.new { logger Logger.new(IO::NULL); read container(:json, file: '#{dir}/x.json').tap { File.write('#{dir}/x.json', '[]') }; write container(:csv, file: '#{dir}/y.csv') }.run" assert_empty loaded_after(code) end end def test_each_plugin_loads_only_its_gem with_tmpdir do |dir| assert_equal %w[sqlite3], loaded_after("DataPipeline::SqliteStorage.new(database: ':memory:').close") assert_equal %w[caxlsx], loaded_after("DataPipeline::ExcelStorage.new(file: '#{dir}/a.xlsx').write([{ 'a' => 1 }])") assert_equal %w[roo caxlsx].sort, loaded_after("DataPipeline::ExcelStorage.new(file: '#{dir}/b.xlsx').write([{ 'a' => 1 }]); DataPipeline::ExcelStorage.new(file: '#{dir}/b.xlsx').read").sort assert_equal %w[http], loaded_after("DataPipeline::RestStorage.new(url: 'http://localhost')") end end def test_missing_gem_message plugin = Class.new(DataPipeline::StoragePlugin) { def initialize(**) = self.class.require_gem('gibtsnicht_gem') } Object.const_set(:GibtsNichtStorage, plugin) unless defined?(GibtsNichtStorage) error = assert_raises(LoadError) { GibtsNichtStorage.new } assert_includes error.message, "gem 'gibtsnicht_gem'" end end