parallel-rspec 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.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2820fc1f77e7c926911e9697230f45b46028d82d
4
+ data.tar.gz: 11ad9491f170694b49296ed590c189f964ca736f
5
+ SHA512:
6
+ metadata.gz: cfaeda33e78559f68b2d013883daa58523b71bcc108db0d627385d7e3657152057bb6526fa9f860413c976e7a9d8a8f5ddf4ff036831aab289f7b3d7a19ae9d8
7
+ data.tar.gz: c9d96690ad7703cd798ea486f7ae18c4c6f3cd5d7d84b5844d2d0dd1c5008438380c5e22911331cb8693c264138d2d2735637fd2a79ceef2a7a3ba07c60b84d3
@@ -0,0 +1,54 @@
1
+
2
+ # Created by https://www.gitignore.io/api/ruby
3
+
4
+ ### Ruby ###
5
+ *.gem
6
+ *.rbc
7
+ /.config
8
+ /coverage/
9
+ /InstalledFiles
10
+ /pkg/
11
+ /spec/reports/
12
+ /spec/examples.txt
13
+ /test/tmp/
14
+ /test/version_tmp/
15
+ /tmp/
16
+
17
+ # Used by dotenv library to load environment variables.
18
+ # .env
19
+
20
+ ## Specific to RubyMotion:
21
+ .dat*
22
+ .repl_history
23
+ build/
24
+ *.bridgesupport
25
+ build-iPhoneOS/
26
+ build-iPhoneSimulator/
27
+
28
+ ## Specific to RubyMotion (use of CocoaPods):
29
+ #
30
+ # We recommend against adding the Pods directory to your .gitignore. However
31
+ # you should judge for yourself, the pros and cons are mentioned at:
32
+ # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
33
+ #
34
+ # vendor/Pods/
35
+
36
+ ## Documentation cache and generated files:
37
+ /.yardoc/
38
+ /_yardoc/
39
+ /doc/
40
+ /rdoc/
41
+
42
+ ## Environment normalization:
43
+ /.bundle/
44
+ /vendor/bundle
45
+ /lib/bundler/man/
46
+
47
+ # for a library or gem, you might want to ignore these files since the code is
48
+ # intended to run in multiple environments; otherwise, check them in:
49
+ Gemfile.lock
50
+ .ruby-version
51
+ .ruby-gemset
52
+
53
+ # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
54
+ .rvmrc
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --require spec_helper
@@ -0,0 +1,19 @@
1
+ Metrics/MethodLength:
2
+ CountComments: false # count full line comments?
3
+ Max: 20
4
+
5
+ Metrics/LineLength:
6
+ Max: 125
7
+
8
+ Metrics/AbcSize:
9
+ Max: 30
10
+
11
+ Style/FileName:
12
+ Exclude:
13
+ - 'lib/parallel-rspec.rb'
14
+
15
+ Style/StringLiterals:
16
+ EnforcedStyle: double_quotes
17
+
18
+ Style/Documentation:
19
+ Enabled: false
@@ -0,0 +1,3 @@
1
+ SimpleCov.start do
2
+ add_filter "/spec/"
3
+ end
@@ -0,0 +1,4 @@
1
+ --markup markdown
2
+ --markup-provider redcarpet
3
+ --no-private
4
+ --hide-api private
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source "https://rubygems.org"
2
+
3
+ gemspec
@@ -0,0 +1,57 @@
1
+ # RSpec::Parallel
2
+
3
+ [![wercker status](https://app.wercker.com/status/214cac59fa2938c9d373983bba71623e/m/master "wercker status")](https://app.wercker.com/project/byKey/214cac59fa2938c9d373983bba71623e)
4
+
5
+ Parallel spec runner for RSpec 3.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ $ gem install parallel-rspec
11
+ ```
12
+
13
+ ## Getting Started / Usage
14
+
15
+ Parallel-rspec bundles `parallel-rspec` binary which can be used directly:
16
+
17
+ ```sh
18
+ $ parallel-rspec spec
19
+ ```
20
+
21
+ If spec/parallel_spec_helper.rb is found, the `parallel-rspec` command loads it before starting the test. Since parallel-rspec uses fork(2) to spawn off workers, you must ensure each worker runs in an isolated environment. Use the `after_fork` hook to reset any global state.
22
+
23
+ ```ruby
24
+ RSpec::Parallel.configure do |config|
25
+ config.after_fork do |worker|
26
+ # Use separate database.
27
+ ActiveRecord::Base.configurations["test"]["database"] << worker.number.to_s
28
+ ActiveRecord::Base.establish_connection(:test)
29
+ end
30
+ end
31
+ ```
32
+
33
+ In this case, your workers assume sequence of databases exist and has right schema already. Rspec-parallel ships with `db:test:prepare_sequential` rake task to prepare them for your Rails application:
34
+
35
+ ```sh
36
+ $ rake db:test:prepare_sequential
37
+ ```
38
+
39
+ ### Controll concurrency
40
+
41
+ The number of workers spawned by parallel-rspec is the number of available CPU cores by default. To controll the concurrency, use `concurrency` configuration option:
42
+
43
+ ```ruby
44
+ RSpec::Parallel.configure do |config|
45
+ config.concurrency = 4
46
+ end
47
+ ```
48
+
49
+ `db:test:prepare_sequential` task takes concurrency as an argument.
50
+
51
+ ```sh
52
+ $ rake "db:test:prepare_sequential[4]"
53
+ ```
54
+
55
+ ## License
56
+
57
+ [MIT](https://github.com/yuku-t/parallel-rspec/blob/master/LICENSE) © [Yuku TAKAHASHI](https://github.com/yuku-t)
@@ -0,0 +1,9 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "rubocop/rake_task"
4
+ require "rspec/parallel/rake_task"
5
+
6
+ RSpec::Core::RakeTask.new("spec")
7
+ RuboCop::RakeTask.new
8
+
9
+ task default: [:rubocop, :spec]
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "parallel-rspec"
4
+
5
+ helper_path = ENV.fetch("RSPEC_PARALLEL_HELPER", "spec/parallel_spec_helper.rb")
6
+ Kernel.load(helper_path) if File.readable?(helper_path)
7
+
8
+ RSpec::Parallel::Runner.new(ARGV).start
@@ -0,0 +1,8 @@
1
+ require "rspec/parallel"
2
+ require "rspec/parallel/configuration"
3
+ require "rspec/parallel/master"
4
+ require "rspec/parallel/railtie" if defined? Rails::Railtie
5
+ require "rspec/parallel/runner"
6
+ require "rspec/parallel/socket_builder"
7
+ require "rspec/parallel/version"
8
+ require "rspec/parallel/worker"
@@ -0,0 +1,21 @@
1
+ require "rspec/parallel/configuration"
2
+
3
+ module RSpec
4
+ module Parallel
5
+ # @return [RSpec::Parallel::Configuration]
6
+ def self.configuration
7
+ @configuration ||= RSpec::Parallel::Configuration.new
8
+ end
9
+
10
+ # Yields the global configuration to a block.
11
+ #
12
+ # @yield [RSpec::Parallel::Configuration]
13
+ # @example
14
+ # RSpec::Parallel.configure do |config|
15
+ # config.bind = "0.0.0.0:8000"
16
+ # end
17
+ def self.configure
18
+ yield configuration if block_given?
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,47 @@
1
+ require "logger"
2
+
3
+ module RSpec
4
+ module Parallel
5
+ # Stores runtime configuration information.
6
+ #
7
+ # @!attribute concurrency
8
+ # @return [Integer]
9
+ class Configuration
10
+ DEFULT_AFTER_FORK = ->(_worker) {}
11
+
12
+ def after_fork(&block)
13
+ @after_fork_block = block_given? ? block : DEFULT_AFTER_FORK
14
+ end
15
+
16
+ def after_fork_block
17
+ @after_fork_block ||= DEFULT_AFTER_FORK
18
+ end
19
+
20
+ # @return [Integer]
21
+ def concurrency
22
+ @concurrency ||=
23
+ if File.exist?("/proc/cpuinfo")
24
+ File.read("/proc/cpuinfo").split("\n").grep(/processor/).size
25
+ elsif RUBY_PLATFORM =~ /darwin/
26
+ `/usr/sbin/sysctl -n hw.activecpu`.to_i
27
+ else
28
+ 2
29
+ end
30
+ end
31
+
32
+ # @return [Logger]
33
+ def logger
34
+ @logger ||= Logger.new(STDERR).tap do |logger|
35
+ logger.level = log_level
36
+ end
37
+ end
38
+
39
+ # @return [Integer]
40
+ def log_level
41
+ @log_level ||= Logger::WARN
42
+ end
43
+
44
+ attr_writer :concurrency, :logger, :log_level
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,7 @@
1
+ module RSpec
2
+ module Parallel
3
+ class Error < StandardError; end
4
+
5
+ class EmptyQueue < Error; end
6
+ end
7
+ end
@@ -0,0 +1,80 @@
1
+ require "English"
2
+ require "fileutils"
3
+ require "rspec/core"
4
+ require "socket"
5
+
6
+ require_relative "errors"
7
+ require_relative "protocol"
8
+ require_relative "socket_builder"
9
+
10
+ module RSpec
11
+ module Parallel
12
+ class Master
13
+ # @param args [Array<String>]
14
+ attr_reader :args
15
+
16
+ # @note RSpec must be configured ahead
17
+ # @param args [Array<String>] command line arguments
18
+ def initialize(args)
19
+ @args = args
20
+ @path = "/tmp/parallel-rspec-#{$PID}.sock"
21
+ @files_to_run = ::RSpec.configuration.files_to_run.uniq
22
+ @server = ::UNIXServer.new(@path)
23
+ end
24
+
25
+ # @return [void]
26
+ def close
27
+ server.close
28
+ end
29
+
30
+ # @return [void]
31
+ def run
32
+ until files_to_run.empty?
33
+ rs, _ws, _es = IO.select([server])
34
+ rs.each do |s|
35
+ socket = s.accept
36
+ method, _data = socket.gets.strip.split("\t", 2)
37
+ case method
38
+ when Protocol::POP
39
+ path = files_to_run.pop
40
+ RSpec::Parallel.configuration.logger.info("Deliver #{path}")
41
+ socket.write(path)
42
+ when Protocol::PING
43
+ socket.write("ok")
44
+ end
45
+ socket.close
46
+ end
47
+ end
48
+ close
49
+ remove_socket_file
50
+ end
51
+
52
+ # Create a socket builder which builds a socket to
53
+ # connect with the master process.
54
+ #
55
+ # @return [RSpec::Parallel::SocketBuilder]
56
+ def socket_builder
57
+ SocketBuilder.new(path)
58
+ end
59
+
60
+ private
61
+
62
+ # @return [String, nil] path to unix domain socket
63
+ attr_reader :path
64
+
65
+ # @example
66
+ # files_to_run
67
+ # #=> ["spec/rspec/parallel_spec.rb", "spec/rspec/parallel/configuration_spec.rb"]
68
+ # @return [Array<String>]
69
+ attr_reader :files_to_run
70
+
71
+ # @return [UNIXServer]
72
+ attr_reader :server
73
+
74
+ # @return [void]
75
+ def remove_socket_file
76
+ FileUtils.rm(path, force: true)
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,8 @@
1
+ module RSpec
2
+ module Parallel
3
+ module Protocol
4
+ POP = "pop".freeze
5
+ PING = "ping".freeze
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,9 @@
1
+ module RSpec
2
+ module Parallel
3
+ class Engine < ::Rails::Railtie
4
+ rake_tasks do
5
+ require "rspec/parallel/rake_task"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,27 @@
1
+ require "rspec/parallel"
2
+
3
+ namespace :db do
4
+ namespace :test do
5
+ desc "Prepare sequence of databases for parallel-rspec"
6
+ task :prepare_sequential, ["concurrency"] => :environment do |_, args|
7
+ require "active_record/tasks/database_tasks"
8
+ concurrency = Integer(args[:concurrency] || RSpec::Parallel.configuration.concurrency)
9
+
10
+ concurrency.times do |i|
11
+ database = ActiveRecord::Base.configurations["test"]["database"] + i.to_s
12
+ configuration = ActiveRecord::Base.configurations["test"].merge("database" => database)
13
+
14
+ ActiveRecord::Tasks::DatabaseTasks.drop(configuration) unless ENV["CI"]
15
+ puts "Create and load schema to #{database}"
16
+ ActiveRecord::Tasks::DatabaseTasks.create(configuration)
17
+ stdout = $stdout
18
+ begin
19
+ $stdout = File.open(File::NULL, "w")
20
+ ActiveRecord::Tasks::DatabaseTasks.load_schema_for(configuration)
21
+ ensure
22
+ $stdout = stdout
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,82 @@
1
+ require "English"
2
+
3
+ require_relative "master"
4
+ require_relative "worker"
5
+
6
+ module RSpec
7
+ module Parallel
8
+ class Runner
9
+ # @return [Array<Integer>] array of pids of spawned worker processes
10
+ attr_reader :pids
11
+
12
+ # @param args [Array<String>] command line arguments
13
+ def initialize(args)
14
+ @args = args
15
+ @pids = []
16
+
17
+ # Configure RSpec core before initialize master instance and spawning
18
+ # worker processes to share its configuration.
19
+ configure_rspec
20
+ @master = Master.new(args)
21
+ end
22
+
23
+ # @return [void]
24
+ def start
25
+ RSpec::Parallel.configuration.concurrency.times do
26
+ spawn_worker
27
+ end
28
+ master.run
29
+ Process.waitall
30
+ ensure
31
+ pids.each.with_index do |pid, index|
32
+ puts "----> output from worker[#{index}]"
33
+ File.open(output_file_path(pid)) do |file|
34
+ puts file.read
35
+ end
36
+ end
37
+ end
38
+
39
+ private
40
+
41
+ # @return [Array<String>]
42
+ attr_reader :args
43
+
44
+ # @return [RSpec::Parallel::Master]
45
+ attr_reader :master
46
+
47
+ # @param master [RSpec::Parallel::Master]
48
+ def spawn_worker
49
+ pid = Kernel.fork do
50
+ master.close
51
+
52
+ File.open(output_file_path($PID), "w") do |file|
53
+ # Redirect stdout and stderr to temp file
54
+ STDOUT.reopen(file)
55
+ STDERR.reopen(STDOUT)
56
+ STDOUT.sync = STDERR.sync = true
57
+
58
+ worker = Worker.new(master, pids.size)
59
+ $0 = "parallel-rspec worker [#{worker.number}]"
60
+ RSpec::Parallel.configuration.after_fork_block.call(worker)
61
+ worker.run
62
+ end
63
+
64
+ Kernel.exit! # avoid running any `at_exit` functions.
65
+ end
66
+ pids << pid
67
+ Process.detach(pid)
68
+ end
69
+
70
+ # @param pid [Integer]
71
+ # @return [String]
72
+ def output_file_path(pid)
73
+ "/tmp/parallel-rspec-worker-#{pid}"
74
+ end
75
+
76
+ def configure_rspec
77
+ options = ::RSpec::Core::ConfigurationOptions.new(args)
78
+ options.configure(::RSpec.configuration)
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,33 @@
1
+ require "socket"
2
+
3
+ module RSpec
4
+ module Parallel
5
+ class SocketBuilder
6
+ def initialize(path)
7
+ @path = path
8
+ end
9
+
10
+ # @return [BasicSocket, nil]
11
+ def run(retry_counter = 3)
12
+ build
13
+ rescue
14
+ retry_counter -= 1
15
+ if retry_counter > 0
16
+ sleep rand
17
+ retry
18
+ end
19
+ nil
20
+ end
21
+
22
+ private
23
+
24
+ # @return [UNIXSocket]
25
+ def build
26
+ ::UNIXSocket.new(path)
27
+ end
28
+
29
+ # @return [String]
30
+ attr_reader :path
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,5 @@
1
+ module RSpec
2
+ module Parallel
3
+ VERSION = "0.1.0".freeze
4
+ end
5
+ end
@@ -0,0 +1,118 @@
1
+ require_relative "protocol"
2
+
3
+ module RSpec
4
+ module Parallel
5
+ class Worker
6
+ # @return [Integer]
7
+ attr_reader :number
8
+
9
+ # @param master [RSpec::Parallel::Master]
10
+ # @param number [Integer]
11
+ def initialize(master, number)
12
+ RSpec::Parallel.configuration.logger.info("Initialize Iterator")
13
+ @iterator = Iterator.new(master.socket_builder)
14
+ @number = number
15
+ RSpec::Parallel.configuration.logger.info("Initialize SpecRunner")
16
+ @spec_runner = SpecRunner.new(master.args)
17
+ end
18
+
19
+ # @return [void]
20
+ def run
21
+ iterator.ping
22
+ spec_runner.run_specs(iterator).to_i
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :iterator, :spec_runner
28
+
29
+ class Iterator
30
+ include Enumerable
31
+
32
+ # @param socket_builder [RSpec::Parallel::SocketBuilder]
33
+ def initialize(socket_builder)
34
+ @socket_builder = socket_builder
35
+ end
36
+
37
+ # @return [void]
38
+ def ping
39
+ loop do
40
+ socket = connect_to_distributor
41
+ if socket.nil?
42
+ RSpec::Parallel.configuration.logger.info("Sleep a little to wait master process")
43
+ sleep 0.5
44
+ next
45
+ end
46
+ RSpec::Parallel.configuration.logger.info("Send PING request")
47
+ socket.puts(Protocol::PING)
48
+ # TODO: handle socket error and check pong message
49
+ IO.select([socket])
50
+ socket.read(65_536)
51
+ socket.close
52
+ break
53
+ end
54
+ end
55
+
56
+ # @yield [RSpec::Core::ExampleGroup]
57
+ def each
58
+ loop do
59
+ socket = connect_to_distributor
60
+ break if socket.nil?
61
+ RSpec::Parallel.configuration.logger.info("Send POP request")
62
+ socket.puts(Protocol::POP)
63
+ _, _, es = IO.select([socket], nil, [socket])
64
+ unless es.empty?
65
+ RSpec::Parallel.configuration.logger.error("Socket error occurs")
66
+ break
67
+ end
68
+ path = socket.read(65_536)
69
+ socket.close
70
+ RSpec.world.example_groups.clear
71
+ RSpec::Parallel.configuration.logger.info("Load #{path}")
72
+ Kernel.load path
73
+ RSpec.world.example_groups.each do |example_group|
74
+ yield example_group
75
+ end
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ # @return [RSpec::Parallel::SocketBuilder]
82
+ attr_reader :socket_builder
83
+
84
+ # @return [BasicSocket, nil]
85
+ def connect_to_distributor
86
+ socket_builder.run
87
+ end
88
+ end
89
+
90
+ class SpecRunner < RSpec::Core::Runner
91
+ # @param args [Array<String>]
92
+ def initialize(args)
93
+ options = RSpec::Core::ConfigurationOptions.new(args)
94
+ super(options)
95
+ end
96
+
97
+ # @param example_groups [Array<RSpec::Core::ExampleGroup>]
98
+ # @return [Integer] exit status code
99
+ def run_specs(example_groups)
100
+ # Reset filter manager to run all specs. Just for simplicity
101
+ # TODO: Support config.run_all_when_everything_filtered = true
102
+ @configuration.filter_manager = RSpec::Core::FilterManager.new
103
+
104
+ success = @configuration.reporter.report(0) do |reporter|
105
+ @configuration.with_suite_hooks do
106
+ example_groups.map do |g|
107
+ RSpec::Parallel.configuration.logger.info("Run #{g.inspect}")
108
+ g.run(reporter)
109
+ end.all?
110
+ end
111
+ end && !@world.non_example_failure
112
+
113
+ success ? 0 : @configuration.failure_exit_code
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,27 @@
1
+ lib = File.expand_path("../lib", __FILE__)
2
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
+
4
+ require "rspec/parallel/version"
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "parallel-rspec"
8
+ spec.authors = ["Yuku Takahashi"]
9
+ spec.email = ["taka84u9@gmail.com"]
10
+ spec.version = RSpec::Parallel::VERSION
11
+ spec.summary = "Parallel spec runner for RSpec 3"
12
+ spec.license = "MIT"
13
+ spec.required_ruby_version = ">= 2.0"
14
+ spec.homepage = "https://github.com/yuku-t/parallel-rspec"
15
+
16
+ spec.executables = ["parallel-rspec"]
17
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^spec/}) }
18
+
19
+ spec.add_dependency "rspec-core", "~> 3.0"
20
+
21
+ spec.add_development_dependency "rake", "~> 11.3"
22
+ spec.add_development_dependency "redcarpet", "~> 3.3.4"
23
+ spec.add_development_dependency "rspec", "~> 3.5.0"
24
+ spec.add_development_dependency "rubocop", "~> 0.45.0"
25
+ spec.add_development_dependency "simplecov", "~> 0.12.0"
26
+ spec.add_development_dependency "yard", "~> 0.9.5"
27
+ end
@@ -0,0 +1,16 @@
1
+ box: ruby
2
+ build:
3
+ steps:
4
+ - bundle-install
5
+ rubocop:
6
+ steps:
7
+ - bundle-install
8
+ - script:
9
+ name: rubocop
10
+ code: bundle exec rake rubocop
11
+ rspec:
12
+ steps:
13
+ - bundle-install
14
+ - script:
15
+ name: rspec
16
+ code: bundle exec rake spec
metadata ADDED
@@ -0,0 +1,166 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: parallel-rspec
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Yuku Takahashi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-12-31 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec-core
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '11.3'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '11.3'
41
+ - !ruby/object:Gem::Dependency
42
+ name: redcarpet
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: 3.3.4
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: 3.3.4
55
+ - !ruby/object:Gem::Dependency
56
+ name: rspec
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 3.5.0
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 3.5.0
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubocop
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 0.45.0
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 0.45.0
83
+ - !ruby/object:Gem::Dependency
84
+ name: simplecov
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: 0.12.0
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: 0.12.0
97
+ - !ruby/object:Gem::Dependency
98
+ name: yard
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - "~>"
102
+ - !ruby/object:Gem::Version
103
+ version: 0.9.5
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - "~>"
109
+ - !ruby/object:Gem::Version
110
+ version: 0.9.5
111
+ description:
112
+ email:
113
+ - taka84u9@gmail.com
114
+ executables:
115
+ - parallel-rspec
116
+ extensions: []
117
+ extra_rdoc_files: []
118
+ files:
119
+ - ".gitignore"
120
+ - ".rspec"
121
+ - ".rubocop.yml"
122
+ - ".simplecov"
123
+ - ".yardopts"
124
+ - Gemfile
125
+ - README.md
126
+ - Rakefile
127
+ - bin/parallel-rspec
128
+ - lib/parallel-rspec.rb
129
+ - lib/rspec/parallel.rb
130
+ - lib/rspec/parallel/configuration.rb
131
+ - lib/rspec/parallel/errors.rb
132
+ - lib/rspec/parallel/master.rb
133
+ - lib/rspec/parallel/protocol.rb
134
+ - lib/rspec/parallel/railtie.rb
135
+ - lib/rspec/parallel/rake_task.rb
136
+ - lib/rspec/parallel/runner.rb
137
+ - lib/rspec/parallel/socket_builder.rb
138
+ - lib/rspec/parallel/version.rb
139
+ - lib/rspec/parallel/worker.rb
140
+ - parallel-rspec.gemspec
141
+ - wercker.yml
142
+ homepage: https://github.com/yuku-t/parallel-rspec
143
+ licenses:
144
+ - MIT
145
+ metadata: {}
146
+ post_install_message:
147
+ rdoc_options: []
148
+ require_paths:
149
+ - lib
150
+ required_ruby_version: !ruby/object:Gem::Requirement
151
+ requirements:
152
+ - - ">="
153
+ - !ruby/object:Gem::Version
154
+ version: '2.0'
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ requirements:
157
+ - - ">="
158
+ - !ruby/object:Gem::Version
159
+ version: '0'
160
+ requirements: []
161
+ rubyforge_project:
162
+ rubygems_version: 2.5.1
163
+ signing_key:
164
+ specification_version: 4
165
+ summary: Parallel spec runner for RSpec 3
166
+ test_files: []