enkessler/cuke_slicer

View on GitHub
lib/cuke_slicer/slicer.rb

Summary

Maintainability
A
45 mins
Test Coverage
require 'cuke_slicer/extractors/directory_extractor'
require 'cuke_slicer/extractors/file_extractor'
require 'cuke_slicer/filters/filter_set'

# TODO: refactor all of this
# rubocop:disable Metrics/AbcSize, Style/OptionalArguments
module CukeSlicer

  # The object responsible for slicing up a Cucumber test suite into discrete test cases.
  class Slicer

    # Slices up the given location into individual test cases.
    #
    # The location chosen for slicing can be a file or directory path. Optional filters can be provided in order to
    # ignore certain kinds of test cases. See #known_filters for the available option types. Most options are either a
    # string or regular expression, although arrays of the same can be given instead if more than one filter is desired.
    #
    # A block can be provided as a filter which can allow for maximal filtering flexibility. Note, however, that this
    # exposes the underlying modeling objects and knowledge of how they work is then required to make good use of the
    # filter.
    #
    # Finally, the test cases can be provided as a collection of file:line strings or as a collection of the object
    # types used to represent test cases by the underlying modeling library.
    #
    # @param target [String] the location that will be sliced up
    # @param filters [Hash] the filters that will be applied to the sliced test cases
    # @param format [Symbol] the type of output: :file_line or :test_object
    def slice(target, filters = {}, format, &block)
      validate_target(target)
      validate_filters(filters)
      validate_format(format)

      begin
        target = File.directory?(target) ? CukeModeler::Directory.new(target) : CukeModeler::FeatureFile.new(target)
      rescue => e
        raise e unless e.message =~ /lexing|parsing/i
        raise(ArgumentError, "A syntax or lexing problem was encountered while trying to parse #{target}")
      end

      if target.is_a?(CukeModeler::Directory)
        DirectoryExtractor.new.extract(target, filters, format, &block)
      else
        FileExtractor.new.extract(target, filters, format, &block)
      end
    end

    # The filtering options that are currently supported by the slicer.
    def self.known_filters
      %i[excluded_tags
         included_tags
         excluded_paths
         included_paths]
    end


    private


    def validate_target(target)
      raise(ArgumentError, "File or directory '#{target}' does not exist") unless File.exist?(target.to_s)
    end

    def validate_filters(filters)
      filter_sets = filters.map { |filter_type, value| FilterSet.new(filter_type, value) }
      filter_sets.each(&:validate)
    end

    def validate_format(format)
      raise(ArgumentError, "Invalid Output Format: #{format}") unless %i[test_object file_line].include?(format)
    end

  end
end
# rubocop:enable Metrics/AbcSize, Style/OptionalArguments