Class: Canopus::TestRunner::Discovery
- Inherits:
-
Object
- Object
- Canopus::TestRunner::Discovery
- Defined in:
- lib/canopus/test_runner/discovery.rb
Constant Summary collapse
- MAX_FILES =
50_000- MAX_TEST_FILES =
2_000- MAX_FILE_BYTES =
1 << 20
- MAX_TESTS =
10_000- MAX_DEPTH =
64- MAX_PATH_BYTES =
TestRunner::MAX_PATH_BYTES
- MAX_ADAPTERS =
16- MAX_NAME_BYTES =
4_096- MAX_GROUPS =
32
Instance Attribute Summary collapse
-
#root ⇒ Object
readonly
Returns the value of attribute root.
Instance Method Summary collapse
- #discover(cancelled: -> { false }) ⇒ Object
-
#initialize(root:, ignore: nil, adapters: [Minitest.new, RSpec.new]) ⇒ Discovery
constructor
A new instance of Discovery.
Constructor Details
#initialize(root:, ignore: nil, adapters: [Minitest.new, RSpec.new]) ⇒ Discovery
Returns a new instance of Discovery.
18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/canopus/test_runner/discovery.rb', line 18 def initialize(root:, ignore: nil, adapters: [Minitest.new, RSpec.new]) @root = File.realpath(root) raise ArgumentError, "test root must be a directory" unless File.directory?(@root) raise ArgumentError, "ignore must respond to ignored?" if ignore && !ignore.respond_to?(:ignored?) unless adapters.is_a?(Array) && !adapters.empty? && adapters.length <= MAX_ADAPTERS && adapters.all? { |adapter| adapter.respond_to?(:candidate?) && adapter.respond_to?(:discover) } raise ArgumentError, "test adapters must support candidate? and discover" end @ignore, @adapters = ignore, adapters.dup.freeze end |
Instance Attribute Details
#root ⇒ Object (readonly)
Returns the value of attribute root.
16 17 18 |
# File 'lib/canopus/test_runner/discovery.rb', line 16 def root @root end |
Instance Method Details
#discover(cancelled: -> { false }) ⇒ Object
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/canopus/test_runner/discovery.rb', line 30 def discover(cancelled: -> { false }) raise ArgumentError, "cancelled must respond to call" unless cancelled.respond_to?(:call) require "prism" tests, files, candidates = [], 0, 0 ignore = BoundedIgnore.new(root, delegate: @ignore, cancelled: cancelled) walker = SafeWalker.new(root, ignore: ignore, hidden: true, follow_symlinks: false, max_depth: MAX_DEPTH, cancelled: cancelled) walker.each do |relative| break if cancelled.call || (files += 1) > MAX_FILES || tests.length >= MAX_TESTS relative = TestRunner.normalize_path(relative) next unless relative adapters = @adapters.select { |adapter| adapter.candidate?(relative) } next if adapters.empty? break if (candidates += 1) > MAX_TEST_FILES source = test_source(relative) next unless source parsed = Prism.parse(source) next unless parsed.success? adapters.each do |adapter| remaining = MAX_TESTS - tests.length break if remaining <= 0 || cancelled.call discovered = adapter.discover(parsed.value, path: relative, limit: remaining, cancelled: cancelled) next unless discovered.is_a?(Array) discovered.first(remaining).each { |test| tests << test if valid_test?(test, relative) } end rescue Errno::ENOENT, Errno::EACCES, Errno::ELOOP, Errno::ENOTDIR, EncodingError, ArgumentError next end tests.sort_by! { |test| [test.path, test.line, test.column, test.framework.to_s, test.name] } tests.freeze end |