parallel-rspec 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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: []