rspec-atoms 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +86 -0
- data/exe/rspec-atoms +6 -0
- data/lib/rspec_atoms/cli.rb +69 -0
- data/lib/rspec_atoms/discover.rb +55 -0
- data/lib/rspec_atoms/discovery_formatter.rb +25 -0
- data/lib/rspec_atoms/example_id.rb +17 -0
- data/lib/rspec_atoms/junit_formatter.rb +30 -0
- data/lib/rspec_atoms/run.rb +53 -0
- data/lib/rspec_atoms/version.rb +5 -0
- data/lib/rspec_atoms.rb +7 -0
- metadata +144 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: fa40b012635a3c9f62c31c5977cbd9b17b4e51ac7739c19106597c9f85b06fea
|
|
4
|
+
data.tar.gz: d2a3f0fbd30b9f279c5321dd86e43bacf0884efa418fd7597cea866c5e360359
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: b81face24d35cb9a72209b013965279e65d6fe94d636fb2f07736e41b063375c35041eb17e33ddf6340518b87f8c81eca331ad4602dfb8b471de7523026b94bb
|
|
7
|
+
data.tar.gz: d2efc74f299d142585393684efc4d7bb35cab4ee7a6c36c4d5bd54d0bd72d48f17906a6a559c3f3f8352cba613cfc686122e7ec88c24bb6abd9c5af191141fbb
|
data/LICENSE.txt
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 José Carbone
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# RSpec Atoms
|
|
2
|
+
|
|
3
|
+
CircleCI usually splits RSpec by file. When tests run across parallel instances, a
|
|
4
|
+
slower feature spec can keep one worker busy while the others sit idle, even when
|
|
5
|
+
its individual examples are small.
|
|
6
|
+
|
|
7
|
+
Splitting a cohesive spec into several files only to satisfy the CI scheduler is
|
|
8
|
+
unnecessary. `rspec-atoms` exposes each runnable RSpec example as a schedulable
|
|
9
|
+
atom while preserving shared setup, contexts, and readable JUnit names.
|
|
10
|
+
|
|
11
|
+
The gem was designed for CircleCI's dynamic test splitting, but it works in any
|
|
12
|
+
environment that needs to run RSpec examples in parallel.
|
|
13
|
+
|
|
14
|
+
CircleCI Smarter Testing is currently in beta. Local validation requires the
|
|
15
|
+
CircleCI `testsuite` plugin; CircleCI's CI containers already include it.
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
Add the gem to your `Gemfile`:
|
|
20
|
+
|
|
21
|
+
```ruby
|
|
22
|
+
group :test do
|
|
23
|
+
gem "rspec-atoms"
|
|
24
|
+
end
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
Then run `bundle install`.
|
|
28
|
+
|
|
29
|
+
## CircleCI configuration
|
|
30
|
+
|
|
31
|
+
Create `.circleci/test-suites.yml`:
|
|
32
|
+
|
|
33
|
+
```yaml
|
|
34
|
+
---
|
|
35
|
+
name: backend tests
|
|
36
|
+
|
|
37
|
+
discover: >-
|
|
38
|
+
RAILS_ENV=test bundle exec rspec-atoms discover spec
|
|
39
|
+
|
|
40
|
+
run: >-
|
|
41
|
+
RAILS_ENV=test bundle exec rspec-atoms run
|
|
42
|
+
--junit "<< outputs.junit >>"
|
|
43
|
+
--
|
|
44
|
+
<< test.atoms >>
|
|
45
|
+
|
|
46
|
+
outputs:
|
|
47
|
+
junit: /tmp/rspec/rspec.xml
|
|
48
|
+
|
|
49
|
+
options:
|
|
50
|
+
dynamic-test-splitting: true
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
`<< test.atoms >>` is replaced by CircleCI with the RSpec example IDs assigned to
|
|
54
|
+
the current batch. `<< outputs.junit >>` resolves to the configured JUnit path so
|
|
55
|
+
CircleCI can locate the report. The gem enables its JUnit formatter automatically;
|
|
56
|
+
the `--junit` option only overrides where the report is written.
|
|
57
|
+
|
|
58
|
+
Invoke the test suite from the CircleCI job:
|
|
59
|
+
|
|
60
|
+
```yaml
|
|
61
|
+
- run:
|
|
62
|
+
name: Run RSpec with dynamic test splitting
|
|
63
|
+
command: |
|
|
64
|
+
mkdir -p /tmp/rspec
|
|
65
|
+
circleci run testsuite "backend tests"
|
|
66
|
+
when: always
|
|
67
|
+
|
|
68
|
+
- store_test_results:
|
|
69
|
+
path: /tmp/rspec
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Local usage
|
|
73
|
+
|
|
74
|
+
```bash
|
|
75
|
+
bundle exec rspec-atoms discover spec
|
|
76
|
+
bundle exec rspec-atoms run -- "spec/models/user_spec.rb[1:2]"
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Local runs write JUnit XML to `tmp/rspec.xml`. Pass `--junit PATH` before `--` to
|
|
80
|
+
use a different path.
|
|
81
|
+
|
|
82
|
+
Validate the CircleCI configuration locally with:
|
|
83
|
+
|
|
84
|
+
```bash
|
|
85
|
+
circleci run testsuite "backend tests" --doctor
|
|
86
|
+
```
|
data/exe/rspec-atoms
ADDED
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "discover"
|
|
4
|
+
require_relative "run"
|
|
5
|
+
require_relative "version"
|
|
6
|
+
|
|
7
|
+
module RSpecAtoms
|
|
8
|
+
class CLI
|
|
9
|
+
EXIT_USAGE = 64
|
|
10
|
+
|
|
11
|
+
def self.start(arguments, output: $stdout, error: $stderr)
|
|
12
|
+
arguments = arguments.dup
|
|
13
|
+
command = arguments.shift
|
|
14
|
+
|
|
15
|
+
case command
|
|
16
|
+
when "discover"
|
|
17
|
+
Discover.call(arguments, output: output, error: error)
|
|
18
|
+
when "run"
|
|
19
|
+
junit_output = extract_option!(
|
|
20
|
+
arguments,
|
|
21
|
+
"--junit",
|
|
22
|
+
default: Run::DEFAULT_JUNIT_OUTPUT
|
|
23
|
+
)
|
|
24
|
+
arguments.shift if arguments.first == "--"
|
|
25
|
+
|
|
26
|
+
Run.call(
|
|
27
|
+
arguments,
|
|
28
|
+
junit_output: junit_output,
|
|
29
|
+
output: output,
|
|
30
|
+
error: error
|
|
31
|
+
)
|
|
32
|
+
when "version", "--version", "-v"
|
|
33
|
+
output.puts(VERSION)
|
|
34
|
+
0
|
|
35
|
+
else
|
|
36
|
+
error.puts(usage)
|
|
37
|
+
EXIT_USAGE
|
|
38
|
+
end
|
|
39
|
+
rescue ArgumentError => exception
|
|
40
|
+
error.puts(exception.message)
|
|
41
|
+
error.puts(usage)
|
|
42
|
+
EXIT_USAGE
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.extract_option!(arguments, option, default:)
|
|
46
|
+
index = arguments.index(option)
|
|
47
|
+
return default unless index
|
|
48
|
+
|
|
49
|
+
value = arguments[index + 1]
|
|
50
|
+
if value.nil? || value.empty? || value == "--"
|
|
51
|
+
raise ArgumentError, "Missing #{option} PATH"
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
arguments.slice!(index, 2)
|
|
55
|
+
value
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def self.usage
|
|
59
|
+
<<~USAGE
|
|
60
|
+
Usage:
|
|
61
|
+
rspec-atoms discover [RSpec arguments]
|
|
62
|
+
rspec-atoms run [--junit PATH] -- [RSpec arguments]
|
|
63
|
+
rspec-atoms version
|
|
64
|
+
USAGE
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
private_class_method :extract_option!, :usage
|
|
68
|
+
end
|
|
69
|
+
end
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec/core"
|
|
4
|
+
require "stringio"
|
|
5
|
+
require "tempfile"
|
|
6
|
+
|
|
7
|
+
require_relative "discovery_formatter"
|
|
8
|
+
|
|
9
|
+
module RSpecAtoms
|
|
10
|
+
module Discover
|
|
11
|
+
module_function
|
|
12
|
+
|
|
13
|
+
def call(arguments, output: $stdout, error: $stderr)
|
|
14
|
+
Tempfile.create(["rspec-atoms", ".txt"]) do |atoms_file|
|
|
15
|
+
runner_output = StringIO.new
|
|
16
|
+
RSpec.configuration.fail_if_no_examples = true
|
|
17
|
+
|
|
18
|
+
status = RSpec::Core::Runner.run(
|
|
19
|
+
rspec_arguments(arguments, atoms_file.path),
|
|
20
|
+
error,
|
|
21
|
+
runner_output
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
if status.zero?
|
|
25
|
+
atoms_file.rewind
|
|
26
|
+
IO.copy_stream(atoms_file, output)
|
|
27
|
+
else
|
|
28
|
+
write_runner_output(runner_output, error)
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
status
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def rspec_arguments(arguments, atoms_path)
|
|
36
|
+
[
|
|
37
|
+
"--dry-run",
|
|
38
|
+
"--no-color",
|
|
39
|
+
"--format",
|
|
40
|
+
"RSpecAtoms::DiscoveryFormatter",
|
|
41
|
+
"--out",
|
|
42
|
+
atoms_path,
|
|
43
|
+
*arguments
|
|
44
|
+
]
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def write_runner_output(runner_output, error)
|
|
48
|
+
content = runner_output.string
|
|
49
|
+
return if content.empty?
|
|
50
|
+
|
|
51
|
+
error.write(content)
|
|
52
|
+
error.write("\n") unless content.end_with?("\n")
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec/core"
|
|
4
|
+
|
|
5
|
+
require_relative "example_id"
|
|
6
|
+
|
|
7
|
+
module RSpecAtoms
|
|
8
|
+
class DiscoveryFormatter
|
|
9
|
+
RSpec::Core::Formatters.register self, :example_started, :close
|
|
10
|
+
|
|
11
|
+
def initialize(output)
|
|
12
|
+
@output = output
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def example_started(notification)
|
|
16
|
+
@output.puts(
|
|
17
|
+
ExampleId.normalize(notification.example.id)
|
|
18
|
+
)
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def close(_notification)
|
|
22
|
+
@output.flush
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module RSpecAtoms
|
|
4
|
+
module ExampleId
|
|
5
|
+
SELECTOR_PATTERN = /\[[^\]]+\]\z/
|
|
6
|
+
|
|
7
|
+
module_function
|
|
8
|
+
|
|
9
|
+
def normalize(value)
|
|
10
|
+
value.to_s.sub(/\A\.\//, "")
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def file_path(value)
|
|
14
|
+
normalize(value).sub(SELECTOR_PATTERN, "")
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "rspec_junit_formatter"
|
|
4
|
+
|
|
5
|
+
require_relative "example_id"
|
|
6
|
+
|
|
7
|
+
module RSpecAtoms
|
|
8
|
+
class JunitFormatter < ::RSpecJUnitFormatter
|
|
9
|
+
RSpec::Core::Formatters.register(
|
|
10
|
+
self,
|
|
11
|
+
:start,
|
|
12
|
+
:stop,
|
|
13
|
+
:dump_summary
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def example_group_file_path_for(notification)
|
|
19
|
+
ExampleId.normalize(notification.example.id)
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def classname_for(notification)
|
|
23
|
+
ExampleId
|
|
24
|
+
.file_path(notification.example.id)
|
|
25
|
+
.sub(%r{\.[^/]*\z}, "")
|
|
26
|
+
.tr("/", ".")
|
|
27
|
+
.gsub(/\A\.+|\.+\z/, "")
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "fileutils"
|
|
4
|
+
require "rspec/core"
|
|
5
|
+
|
|
6
|
+
require_relative "junit_formatter"
|
|
7
|
+
|
|
8
|
+
module RSpecAtoms
|
|
9
|
+
module Run
|
|
10
|
+
DEFAULT_JUNIT_OUTPUT = "tmp/rspec.xml"
|
|
11
|
+
|
|
12
|
+
module_function
|
|
13
|
+
|
|
14
|
+
def call(
|
|
15
|
+
arguments,
|
|
16
|
+
junit_output: DEFAULT_JUNIT_OUTPUT,
|
|
17
|
+
output: $stdout,
|
|
18
|
+
error: $stderr
|
|
19
|
+
)
|
|
20
|
+
ensure_output_directory(junit_output)
|
|
21
|
+
|
|
22
|
+
RSpec::Core::Runner.run(
|
|
23
|
+
inject_formatters(arguments, junit_output),
|
|
24
|
+
error,
|
|
25
|
+
output
|
|
26
|
+
)
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def inject_formatters(arguments, junit_output)
|
|
30
|
+
separator_index = arguments.index("--") || arguments.length
|
|
31
|
+
options = arguments[0...separator_index]
|
|
32
|
+
selectors = arguments[separator_index..] || []
|
|
33
|
+
|
|
34
|
+
[
|
|
35
|
+
*options,
|
|
36
|
+
"--format",
|
|
37
|
+
"progress",
|
|
38
|
+
"--format",
|
|
39
|
+
"RSpecAtoms::JunitFormatter",
|
|
40
|
+
"--out",
|
|
41
|
+
junit_output,
|
|
42
|
+
*selectors
|
|
43
|
+
]
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def ensure_output_directory(junit_output)
|
|
47
|
+
directory = File.dirname(junit_output)
|
|
48
|
+
return if directory == "."
|
|
49
|
+
|
|
50
|
+
FileUtils.mkdir_p(directory)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
data/lib/rspec_atoms.rb
ADDED
metadata
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: rspec-atoms
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jose Carbone
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rspec-core
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '3.13'
|
|
19
|
+
- - "<"
|
|
20
|
+
- !ruby/object:Gem::Version
|
|
21
|
+
version: '4'
|
|
22
|
+
type: :runtime
|
|
23
|
+
prerelease: false
|
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
25
|
+
requirements:
|
|
26
|
+
- - ">="
|
|
27
|
+
- !ruby/object:Gem::Version
|
|
28
|
+
version: '3.13'
|
|
29
|
+
- - "<"
|
|
30
|
+
- !ruby/object:Gem::Version
|
|
31
|
+
version: '4'
|
|
32
|
+
- !ruby/object:Gem::Dependency
|
|
33
|
+
name: rspec_junit_formatter
|
|
34
|
+
requirement: !ruby/object:Gem::Requirement
|
|
35
|
+
requirements:
|
|
36
|
+
- - ">="
|
|
37
|
+
- !ruby/object:Gem::Version
|
|
38
|
+
version: '0.6'
|
|
39
|
+
- - "<"
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '1'
|
|
42
|
+
type: :runtime
|
|
43
|
+
prerelease: false
|
|
44
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
45
|
+
requirements:
|
|
46
|
+
- - ">="
|
|
47
|
+
- !ruby/object:Gem::Version
|
|
48
|
+
version: '0.6'
|
|
49
|
+
- - "<"
|
|
50
|
+
- !ruby/object:Gem::Version
|
|
51
|
+
version: '1'
|
|
52
|
+
- !ruby/object:Gem::Dependency
|
|
53
|
+
name: rake
|
|
54
|
+
requirement: !ruby/object:Gem::Requirement
|
|
55
|
+
requirements:
|
|
56
|
+
- - ">="
|
|
57
|
+
- !ruby/object:Gem::Version
|
|
58
|
+
version: '13'
|
|
59
|
+
type: :development
|
|
60
|
+
prerelease: false
|
|
61
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
62
|
+
requirements:
|
|
63
|
+
- - ">="
|
|
64
|
+
- !ruby/object:Gem::Version
|
|
65
|
+
version: '13'
|
|
66
|
+
- !ruby/object:Gem::Dependency
|
|
67
|
+
name: rexml
|
|
68
|
+
requirement: !ruby/object:Gem::Requirement
|
|
69
|
+
requirements:
|
|
70
|
+
- - ">="
|
|
71
|
+
- !ruby/object:Gem::Version
|
|
72
|
+
version: '0'
|
|
73
|
+
type: :development
|
|
74
|
+
prerelease: false
|
|
75
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
76
|
+
requirements:
|
|
77
|
+
- - ">="
|
|
78
|
+
- !ruby/object:Gem::Version
|
|
79
|
+
version: '0'
|
|
80
|
+
- !ruby/object:Gem::Dependency
|
|
81
|
+
name: rspec
|
|
82
|
+
requirement: !ruby/object:Gem::Requirement
|
|
83
|
+
requirements:
|
|
84
|
+
- - ">="
|
|
85
|
+
- !ruby/object:Gem::Version
|
|
86
|
+
version: '3.13'
|
|
87
|
+
- - "<"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '4'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - ">="
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '3.13'
|
|
97
|
+
- - "<"
|
|
98
|
+
- !ruby/object:Gem::Version
|
|
99
|
+
version: '4'
|
|
100
|
+
description: |
|
|
101
|
+
Discovers runnable RSpec examples as RSpec IDs and emits matching JUnit
|
|
102
|
+
identities for CircleCI Smarter Testing.
|
|
103
|
+
email:
|
|
104
|
+
- joseignaciocarbone@gmail.com
|
|
105
|
+
executables:
|
|
106
|
+
- rspec-atoms
|
|
107
|
+
extensions: []
|
|
108
|
+
extra_rdoc_files: []
|
|
109
|
+
files:
|
|
110
|
+
- LICENSE.txt
|
|
111
|
+
- README.md
|
|
112
|
+
- exe/rspec-atoms
|
|
113
|
+
- lib/rspec_atoms.rb
|
|
114
|
+
- lib/rspec_atoms/cli.rb
|
|
115
|
+
- lib/rspec_atoms/discover.rb
|
|
116
|
+
- lib/rspec_atoms/discovery_formatter.rb
|
|
117
|
+
- lib/rspec_atoms/example_id.rb
|
|
118
|
+
- lib/rspec_atoms/junit_formatter.rb
|
|
119
|
+
- lib/rspec_atoms/run.rb
|
|
120
|
+
- lib/rspec_atoms/version.rb
|
|
121
|
+
homepage: https://github.com/josesei/rspec-atoms
|
|
122
|
+
licenses:
|
|
123
|
+
- MIT
|
|
124
|
+
metadata:
|
|
125
|
+
rubygems_mfa_required: 'true'
|
|
126
|
+
source_code_uri: https://github.com/josesei/rspec-atoms
|
|
127
|
+
rdoc_options: []
|
|
128
|
+
require_paths:
|
|
129
|
+
- lib
|
|
130
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
131
|
+
requirements:
|
|
132
|
+
- - ">="
|
|
133
|
+
- !ruby/object:Gem::Version
|
|
134
|
+
version: '3.4'
|
|
135
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
136
|
+
requirements:
|
|
137
|
+
- - ">="
|
|
138
|
+
- !ruby/object:Gem::Version
|
|
139
|
+
version: '0'
|
|
140
|
+
requirements: []
|
|
141
|
+
rubygems_version: 3.6.9
|
|
142
|
+
specification_version: 4
|
|
143
|
+
summary: Split RSpec suites by runnable example
|
|
144
|
+
test_files: []
|