File: Test%2BDiscovery.swift

package info (click to toggle)
swiftlang 6.2.3-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,856,264 kB
  • sloc: cpp: 9,995,718; ansic: 2,234,019; asm: 1,092,167; python: 313,940; objc: 82,726; f90: 80,126; lisp: 38,373; pascal: 25,580; sh: 20,378; ml: 5,058; perl: 4,751; makefile: 4,725; awk: 3,535; javascript: 3,018; xml: 918; fortran: 664; cs: 573; ruby: 396
file content (114 lines) | stat: -rw-r--r-- 4,106 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
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
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2023–2025 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for Swift project authors
//

@_spi(Experimental) @_spi(ForToolsIntegrationOnly) private import _TestDiscovery
private import _TestingInternals

extension Test {
  /// A type that encapsulates test content records that produce instances of
  /// ``Test``.
  ///
  /// This type is necessary because such test content records produce an
  /// indirect `async` accessor function rather than directly producing
  /// instances of ``Test``, but functions are non-nominal types and cannot
  /// directly conform to protocols.
  fileprivate struct Generator: DiscoverableAsTestContent, RawRepresentable {
    static var testContentKind: TestContentKind {
      "test"
    }

    var rawValue: @Sendable () async -> Test
  }

  /// Store the test generator function into the given memory.
  ///
  /// - Parameters:
  ///   - generator: The generator function to store.
  ///   - outValue: The uninitialized memory to store `generator` into.
  ///   - typeAddress: A pointer to the expected type of `generator` as passed
  ///     to the test content record calling this function.
  ///
  /// - Returns: Whether or not `generator` was stored into `outValue`.
  ///
  /// - Warning: This function is used to implement the `@Test` macro. Do not
  ///   use it directly.
#if compiler(>=6.2)
  @safe
#endif
  public static func __store(
    _ generator: @escaping @Sendable () async -> Test,
    into outValue: UnsafeMutableRawPointer,
    asTypeAt typeAddress: UnsafeRawPointer
  ) -> CBool {
#if !hasFeature(Embedded)
    guard typeAddress.load(as: Any.Type.self) == Generator.self else {
      return false
    }
#endif
    outValue.initializeMemory(as: Generator.self, to: .init(rawValue: generator))
    return true
  }

  /// All available ``Test`` instances in the process, according to the runtime.
  ///
  /// The order of values in this sequence is unspecified.
  static var all: some Sequence<Self> {
    get async {
      // The result is a set rather than an array to deduplicate tests that were
      // generated multiple times (e.g. from multiple discovery modes or from
      // defective test records.)
      var result = Set<Self>()

      // Figure out which discovery mechanism to use. By default, we'll use both
      // the legacy and new mechanisms, but we can set an environment variable
      // to explicitly select one or the other. When we remove legacy support,
      // we can also remove this enumeration and environment variable check.
#if !SWT_NO_LEGACY_TEST_DISCOVERY
      let (useNewMode, useLegacyMode) = switch Environment.flag(named: "SWT_USE_LEGACY_TEST_DISCOVERY") {
      case .none:
        (true, true)
      case .some(true):
        (false, true)
      case .some(false):
        (true, false)
      }
#else
      let useNewMode = true
#endif

      // Walk all test content and gather generator functions, then call them in
      // a task group and collate their results.
      if useNewMode {
        let generators = Generator.allTestContentRecords().lazy.compactMap { $0.load() }
        await withTaskGroup { taskGroup in
          for generator in generators {
            taskGroup.addTask { await generator.rawValue() }
          }
          result = await taskGroup.reduce(into: result) { $0.insert($1) }
        }
      }

#if !SWT_NO_LEGACY_TEST_DISCOVERY
      // Perform legacy test discovery if needed.
      if useLegacyMode && result.isEmpty {
        let generators = Generator.allTypeMetadataBasedTestContentRecords().lazy.compactMap { $0.load() }
        await withTaskGroup { taskGroup in
          for generator in generators {
            taskGroup.addTask { await generator.rawValue() }
          }
          result = await taskGroup.reduce(into: result) { $0.insert($1) }
        }
      }
#endif

      return result
    }
  }
}