Class: Spectre::Engine
Constant Summary collapse
- @@current =
nil- @@modules =
[]
Instance Attribute Summary collapse
-
#collections ⇒ Object
readonly
Returns the value of attribute collections.
-
#config ⇒ Object
readonly
Returns the value of attribute config.
-
#contexts ⇒ Object
readonly
Returns the value of attribute contexts.
-
#env ⇒ Object
readonly
Returns the value of attribute env.
-
#environments ⇒ Object
readonly
Returns the value of attribute environments.
-
#formatter ⇒ Object
readonly
Returns the value of attribute formatter.
-
#mixins ⇒ Object
readonly
Returns the value of attribute mixins.
-
#resources ⇒ Object
readonly
Returns the value of attribute resources.
Class Method Summary collapse
-
.current ⇒ Object
The current used engine.
-
.register(cls, *methods) ⇒ Object
Register a class and methods, which should be available in all spectre scopes.
Instance Method Summary collapse
-
#cleanup ⇒ Object
Cleanup temporary files like logs, etc.
-
#describe(desc) ⇒ Object
Describe a test subject.
-
#initialize(config) ⇒ Engine
constructor
A new instance of Engine.
-
#list(config = @config) ⇒ Object
Get a list of specs with the configured filter.
-
#logger ⇒ Object
:nodoc:.
-
#method_missing(method) ⇒ Object
:nodoc:.
-
#mixin(desc, params: [], &block) ⇒ Object
Registers a mixin.
-
#report(runs) ⇒ Object
Create a report with the given runs and configured reporter.
-
#respond_to_missing?(method) ⇒ Boolean
:nodoc:.
-
#run ⇒ Object
Runs specs with the current config.
Constructor Details
#initialize(config) ⇒ Engine
Returns a new instance of Engine.
1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514 1515 1516 1517 1518 1519 1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548 1549 1550 1551 1552 1553 1554 1555 1556 1557 1558 1559 1560 1561 1562 1563 1564 1565 1566 1567 1568 1569 1570 1571 1572 1573 1574 1575 1576 1577 1578 1579 1580 1581 1582 1583 1584 1585 1586 1587 1588 1589 1590 1591 1592 1593 1594 1595 1596 1597 1598 1599 1600 1601 1602 1603 1604 1605 1606 1607 1608 1609 1610 1611 1612 1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623 |
# File 'lib/spectre.rb', line 1502 def initialize config @environments = {} @collections = {} @contexts = [] @mixins = {} @resources = {} @delegates = {} @config = Marshal.load(Marshal.dump(CONFIG)) # Load global config file global_config_file = config['global_config_file'] || File.('~/.config/spectre.yml') if File.exist? global_config_file global_config = load_yaml(global_config_file) @config.deep_merge!(global_config) end # Set working directory so all paths in config # are relative to this directory Dir.chdir(config['work_dir'] || @config['work_dir'] || '.') # Load main spectre config main_config_file = config['config_file'] || @config['config_file'] unless main_config_file.nil? or !File.exist? main_config_file main_config = load_yaml(main_config_file) @config.deep_merge!(main_config) Dir.chdir(File.dirname(main_config_file)) end # Load environments @config['env_patterns'].each do |pattern| Dir.glob(pattern).each do |file_path| loaded_env = load_yaml(file_path) env_name = loaded_env['name'] || DEFAULT_ENV_NAME @environments[env_name] = loaded_env end end # Load and merge partial environment files @config['env_partial_patterns'].each do |pattern| Dir.glob(pattern).each do |file_path| loaded_env = load_yaml(file_path) env_name = loaded_env['name'] || DEFAULT_ENV_NAME @environments[env_name].deep_merge!(loaded_env) if @environments.key?(env_name) end end # Select environment and merge it @config.deep_merge!(@environments[config.delete('selected_env') || DEFAULT_ENV_NAME]) # Load collections @config['collections_patterns'].each do |pattern| Dir.glob(pattern).each do |file_path| @collections.merge! load_yaml(file_path) end end # Use collection if given if config.key? 'collection' collection = @collections[config['collection']] raise "collection #{config['collection']} not found" unless collection @config.deep_merge!(collection) end # Merge property overrides # Merging would override arrays. We don't want this in certain cases, # so merge them manually @config['reporters'].concat(config.delete('reporters')) if config.key? 'reporters' @config['modules'].concat(config.delete('modules')) if config.key? 'modules' @config.deep_merge!(config) # Replace log filename placeholders if @config['log_file'].respond_to? :gsub! @config['log_file'].gsub!('<date>', DateTime.now.strftime('%Y-%m-%d_%H%M%S%3N')) end # Set env before loading specs in order to make it available in spec definitions @env = @config.to_recursive_struct # Load specs # Note that spec files are only loaded once, because of the relative require, # even if the setup function is called multiple times load_files(@config['spec_patterns']) # Load mixins # Mixins are also only loaded once load_files(@config['mixin_patterns']) # Load resources @config['resource_paths'].each do |resource_path| resource_files = Dir.glob File.join(resource_path, '**/*') resource_files.each do |file| relative_file = file .delete_prefix(resource_path) .delete_prefix('/') @resources[relative_file] = File.(file) end end @formatter = Object .const_get(@config['formatter']) .new(@config) # Load modules return unless @config['modules'].is_a? Array @config['modules'].each do |module_name| module_path = File.join(Dir.pwd, module_name) if File.exist? module_path require_relative module_path else require module_name end end end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method) ⇒ Object
:nodoc:
1631 1632 1633 |
# File 'lib/spectre.rb', line 1631 def method_missing(method, *, **, &) @delegates[method]&.send(method, *, **, &) end |
Instance Attribute Details
#collections ⇒ Object (readonly)
Returns the value of attribute collections.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def collections @collections end |
#config ⇒ Object (readonly)
Returns the value of attribute config.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def config @config end |
#contexts ⇒ Object (readonly)
Returns the value of attribute contexts.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def contexts @contexts end |
#env ⇒ Object (readonly)
Returns the value of attribute env.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def env @env end |
#environments ⇒ Object (readonly)
Returns the value of attribute environments.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def environments @environments end |
#formatter ⇒ Object (readonly)
Returns the value of attribute formatter.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def formatter @formatter end |
#mixins ⇒ Object (readonly)
Returns the value of attribute mixins.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def mixins @mixins end |
#resources ⇒ Object (readonly)
Returns the value of attribute resources.
1482 1483 1484 |
# File 'lib/spectre.rb', line 1482 def resources @resources end |
Class Method Details
.current ⇒ Object
The current used engine
1490 1491 1492 |
# File 'lib/spectre.rb', line 1490 def self.current @@current end |
.register(cls, *methods) ⇒ Object
Register a class and methods, which should be available in all spectre scopes
1498 1499 1500 |
# File 'lib/spectre.rb', line 1498 def self.register cls, *methods @@modules << [cls, methods] end |
Instance Method Details
#cleanup ⇒ Object
Cleanup temporary files like logs, etc.
1692 1693 1694 1695 1696 1697 1698 1699 1700 1701 1702 |
# File 'lib/spectre.rb', line 1692 def cleanup Dir.chdir(@config['work_dir']) # Remove all log files explicitly log_file_pattern = @config['log_file'].gsub('<date>', '*') FileUtils.rm_rf(Dir.glob(log_file_pattern), secure: true) # Remove all files (reports) in the output directory out_files_pattern = File.join(@config['out_path'], '*') FileUtils.rm_rf(Dir.glob(out_files_pattern), secure: true) end |
#describe(desc) ⇒ Object
Describe a test subject
1707 1708 1709 1710 1711 1712 1713 1714 1715 1716 |
# File 'lib/spectre.rb', line 1707 def describe(desc, &) file = caller .first .gsub(/:in .*/, '') .gsub(Dir.pwd, '.') DefinitionContext .new(desc, file, self) .instance_eval(&) end |
#list(config = @config) ⇒ Object
Get a list of specs with the configured filter
1643 1644 1645 1646 1647 1648 1649 1650 1651 1652 1653 1654 |
# File 'lib/spectre.rb', line 1643 def list config = @config spec_filter = config['specs'] || [] tag_filter = config['tags'] || [] @contexts .flat_map(&:specs) .select do |spec| (spec_filter.empty? and tag_filter.empty?) or spec_filter.any? { |x| spec.name.match?("^#{x.gsub('*', '.*')}$") } or tag_filter.any? { |x| tag?(spec., x) } end end |
#logger ⇒ Object
:nodoc:
1636 1637 1638 |
# File 'lib/spectre.rb', line 1636 def logger @logger ||= Logger.new(@config, progname: 'spectre') end |
#mixin(desc, params: [], &block) ⇒ Object
Registers a mixin
1721 1722 1723 1724 |
# File 'lib/spectre.rb', line 1721 def mixin desc, params: [], &block file, line = get_call_location(caller_locations) @mixins[desc] = Mixin.new(desc, params, block, file, line) end |
#report(runs) ⇒ Object
Create a report with the given runs and configured reporter.
1681 1682 1683 1684 1685 1686 1687 |
# File 'lib/spectre.rb', line 1681 def report runs @config['reporters'].each do |reporter| Object.const_get(reporter) .new(@config) .report(runs) end end |
#respond_to_missing?(method) ⇒ Boolean
:nodoc:
1626 1627 1628 |
# File 'lib/spectre.rb', line 1626 def respond_to_missing?(method, *) @delegates.key? method end |
#run ⇒ Object
Runs specs with the current config
1659 1660 1661 1662 1663 1664 1665 1666 1667 1668 1669 1670 1671 1672 1673 1674 1675 1676 |
# File 'lib/spectre.rb', line 1659 def run @@modules.each do |mod, methods| target = mod.respond_to?(:new) ? mod.new(@config, logger) : mod methods.each do |method| @delegates[method] = target end end specs = list specs_set = Set.new(list) specs .group_by { |x| x.parent.root } .flat_map { |context, _| context.run(specs_set) } rescue Interrupt # Do nothing here end |