zeus-parallel_tests 0.2.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (39) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -0
  3. data/.rspec +2 -0
  4. data/.rubocop.yml +12 -0
  5. data/Appraisals +19 -0
  6. data/README.md +3 -2
  7. data/Rakefile +2 -13
  8. data/bin/zeus-parallel_tests +8 -10
  9. data/circle.yml +39 -0
  10. data/gemfiles/rails_3_zeus_0.13.gemfile +8 -0
  11. data/gemfiles/rails_3_zeus_0.15.gemfile +8 -0
  12. data/gemfiles/rails_4_zeus_0.13.gemfile +8 -0
  13. data/gemfiles/rails_4_zeus_0.15.gemfile +8 -0
  14. data/lib/zeus/parallel_tests.rb +1 -1
  15. data/lib/zeus/parallel_tests/rails.rb +21 -13
  16. data/lib/zeus/parallel_tests/version.rb +1 -1
  17. data/lib/zeus/parallel_tests/worker.rb +44 -45
  18. data/spec/dummy/Guardfile +4 -4
  19. data/spec/dummy/config/application.rb +2 -9
  20. data/spec/dummy/config/boot.rb +1 -1
  21. data/spec/dummy/config/environments/development.rb +0 -8
  22. data/spec/dummy/config/environments/production.rb +0 -6
  23. data/spec/dummy/config/environments/test.rb +1 -4
  24. data/spec/dummy/custom_plan.rb +1 -0
  25. data/spec/dummy/features/support/env.rb +1 -2
  26. data/spec/dummy/lib/tasks/cucumber.rake +43 -44
  27. data/spec/dummy/spec/spec_helper.rb +4 -4
  28. data/spec/dummy/spec/unit_test_a_spec.rb +3 -3
  29. data/spec/dummy/spec/unit_test_b_spec.rb +3 -3
  30. data/spec/lib/zeus/parallel_tests/worker_spec.rb +28 -30
  31. data/spec/parallel_spec.rb +56 -0
  32. data/spec/spec_helper.rb +2 -10
  33. data/spec/zeus_parallel_tests_spec.rb +16 -0
  34. data/zeus-parallel_tests.gemspec +23 -14
  35. metadata +120 -19
  36. data/.travis.yml +0 -5
  37. data/spec/dummy/Gemfile +0 -31
  38. data/spec/slow/parallel_rspec_spec.rb +0 -56
  39. data/spec/slow/zeus-parallel_tests_spec.rb +0 -29
@@ -3,4 +3,4 @@ require 'rubygems'
3
3
  # Set up gems listed in the Gemfile.
4
4
  ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
5
5
 
6
- require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
6
+ require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
@@ -21,12 +21,4 @@ Dummy::Application.configure do
21
21
 
22
22
  # Only use best-standards-support built into browsers
23
23
  config.action_dispatch.best_standards_support = :builtin
24
-
25
- # Raise exception on mass assignment protection for Active Record models
26
- config.active_record.mass_assignment_sanitizer = :strict
27
-
28
- # Log the query plan for queries taking more than this (works
29
- # with SQLite, MySQL, and PostgreSQL)
30
- config.active_record.auto_explain_threshold_in_seconds = 0.5
31
-
32
24
  end
@@ -11,7 +11,6 @@ Dummy::Application.configure do
11
11
  # Disable Rails's static asset server (Apache or nginx will already do this)
12
12
  config.serve_static_assets = false
13
13
 
14
-
15
14
  # Specifies the header that your server uses for sending files
16
15
  # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
17
16
  # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
@@ -34,7 +33,6 @@ Dummy::Application.configure do
34
33
  # Enable serving of images, stylesheets, and JavaScripts from an asset server
35
34
  # config.action_controller.asset_host = "http://assets.example.com"
36
35
 
37
-
38
36
  # Disable delivery errors, bad email addresses will be ignored
39
37
  # config.action_mailer.raise_delivery_errors = false
40
38
 
@@ -47,8 +45,4 @@ Dummy::Application.configure do
47
45
 
48
46
  # Send deprecation notices to registered listeners
49
47
  config.active_support.deprecation = :notify
50
-
51
- # Log the query plan for queries taking more than this (works
52
- # with SQLite, MySQL, and PostgreSQL)
53
- # config.active_record.auto_explain_threshold_in_seconds = 0.5
54
48
  end
@@ -9,7 +9,7 @@ Dummy::Application.configure do
9
9
 
10
10
  # Configure static asset server for tests with Cache-Control for performance
11
11
  config.serve_static_assets = true
12
- config.static_cache_control = "public, max-age=3600"
12
+ config.static_cache_control = 'public, max-age=3600'
13
13
 
14
14
  # Log error messages when you accidentally call methods on nil
15
15
  config.whiny_nils = true
@@ -29,9 +29,6 @@ Dummy::Application.configure do
29
29
  # ActionMailer::Base.deliveries array.
30
30
  config.action_mailer.delivery_method = :test
31
31
 
32
- # Raise exception on mass assignment protection for Active Record models
33
- config.active_record.mass_assignment_sanitizer = :strict
34
-
35
32
  # Print deprecation notices to the stderr
36
33
  config.active_support.deprecation = :stderr
37
34
  end
@@ -1,3 +1,4 @@
1
+ require 'bundler/setup'
1
2
  require 'zeus/parallel_tests'
2
3
 
3
4
  class CustomPlan < Zeus::ParallelTests::Rails
@@ -33,7 +33,7 @@ ActionController::Base.allow_rescue = false
33
33
  begin
34
34
  DatabaseCleaner.strategy = :transaction
35
35
  rescue NameError
36
- raise "You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it."
36
+ raise 'You need to add database_cleaner to your Gemfile (in the :test group) if you wish to use it.'
37
37
  end
38
38
 
39
39
  # You may also want to configure DatabaseCleaner to use different strategies for certain features and scenarios.
@@ -55,4 +55,3 @@ end
55
55
  # The :transaction strategy is faster, but might give you threading problems.
56
56
  # See https://github.com/cucumber/cucumber-rails/blob/master/features/choose_javascript_database_strategy.feature
57
57
  Cucumber::Rails::Database.javascript_strategy = :truncation
58
-
@@ -4,62 +4,61 @@
4
4
  # instead of editing this one. Cucumber will automatically load all features/**/*.rb
5
5
  # files.
6
6
 
7
+ unless ARGV.any? { |a| a =~ /^gems/ } # Don't load anything when running the gems:* tasks
7
8
 
8
- unless ARGV.any? {|a| a =~ /^gems/} # Don't load anything when running the gems:* tasks
9
+ vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
10
+ $LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
9
11
 
10
- vendored_cucumber_bin = Dir["#{Rails.root}/vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
11
- $LOAD_PATH.unshift(File.dirname(vendored_cucumber_bin) + '/../lib') unless vendored_cucumber_bin.nil?
12
+ begin
13
+ require 'cucumber/rake/task'
12
14
 
13
- begin
14
- require 'cucumber/rake/task'
15
+ namespace :cucumber do
16
+ Cucumber::Rake::Task.new({ ok: 'test:prepare' }, 'Run features that should pass') do |t|
17
+ t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
18
+ t.fork = true # You may get faster startup if you set this to false
19
+ t.profile = 'default'
20
+ end
15
21
 
16
- namespace :cucumber do
17
- Cucumber::Rake::Task.new({:ok => 'test:prepare'}, 'Run features that should pass') do |t|
18
- t.binary = vendored_cucumber_bin # If nil, the gem's binary is used.
19
- t.fork = true # You may get faster startup if you set this to false
20
- t.profile = 'default'
21
- end
22
-
23
- Cucumber::Rake::Task.new({:wip => 'test:prepare'}, 'Run features that are being worked on') do |t|
24
- t.binary = vendored_cucumber_bin
25
- t.fork = true # You may get faster startup if you set this to false
26
- t.profile = 'wip'
27
- end
22
+ Cucumber::Rake::Task.new({ wip: 'test:prepare' }, 'Run features that are being worked on') do |t|
23
+ t.binary = vendored_cucumber_bin
24
+ t.fork = true # You may get faster startup if you set this to false
25
+ t.profile = 'wip'
26
+ end
28
27
 
29
- Cucumber::Rake::Task.new({:rerun => 'test:prepare'}, 'Record failing features and run only them if any exist') do |t|
30
- t.binary = vendored_cucumber_bin
31
- t.fork = true # You may get faster startup if you set this to false
32
- t.profile = 'rerun'
33
- end
28
+ Cucumber::Rake::Task.new({ rerun: 'test:prepare' }, 'Record failing features and run only them if any exist') do |t|
29
+ t.binary = vendored_cucumber_bin
30
+ t.fork = true # You may get faster startup if you set this to false
31
+ t.profile = 'rerun'
32
+ end
34
33
 
35
- desc 'Run all features'
36
- task :all => [:ok, :wip]
34
+ desc 'Run all features'
35
+ task all: [:ok, :wip]
37
36
 
38
- task :statsetup do
39
- require 'rails/code_statistics'
40
- ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features')
41
- ::CodeStatistics::TEST_TYPES << "Cucumber features" if File.exist?('features')
37
+ task :statsetup do
38
+ require 'rails/code_statistics'
39
+ ::STATS_DIRECTORIES << %w(Cucumber\ features features) if File.exist?('features')
40
+ ::CodeStatistics::TEST_TYPES << 'Cucumber features' if File.exist?('features')
41
+ end
42
42
  end
43
- end
44
- desc 'Alias for cucumber:ok'
45
- task :cucumber => 'cucumber:ok'
43
+ desc 'Alias for cucumber:ok'
44
+ task cucumber: 'cucumber:ok'
46
45
 
47
- task :default => :cucumber
46
+ task default: :cucumber
48
47
 
49
- task :features => :cucumber do
50
- STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
51
- end
48
+ task features: :cucumber do
49
+ STDERR.puts "*** The 'features' task is deprecated. See rake -T cucumber ***"
50
+ end
52
51
 
53
- # In case we don't have the generic Rails test:prepare hook, append a no-op task that we can depend upon.
54
- task 'test:prepare' do
55
- end
52
+ # In case we don't have the generic Rails test:prepare hook, append a no-op task that we can depend upon.
53
+ task 'test:prepare' do
54
+ end
56
55
 
57
- task :stats => 'cucumber:statsetup'
58
- rescue LoadError
59
- desc 'cucumber rake task not available (cucumber not installed)'
60
- task :cucumber do
61
- abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
56
+ task stats: 'cucumber:statsetup'
57
+ rescue LoadError
58
+ desc 'cucumber rake task not available (cucumber not installed)'
59
+ task :cucumber do
60
+ abort 'Cucumber rake task is not available. Be sure to install cucumber as a gem or plugin'
61
+ end
62
62
  end
63
- end
64
63
 
65
64
  end
@@ -1,11 +1,11 @@
1
1
  # This file is copied to spec/ when you run 'rails generate rspec:install'
2
- ENV["RAILS_ENV"] ||= 'test'
3
- require File.expand_path("../../config/environment", __FILE__)
2
+ ENV['RAILS_ENV'] ||= 'test'
3
+ require File.expand_path('../../config/environment', __FILE__)
4
4
  require 'rspec/rails'
5
5
 
6
6
  # Requires supporting ruby files with custom matchers and macros, etc,
7
7
  # in spec/support/ and its subdirectories.
8
- Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
8
+ Dir[Rails.root.join('spec/support/**/*.rb')].each { |f| require f }
9
9
 
10
10
  RSpec.configure do |config|
11
11
  # ## Mock Framework
@@ -33,5 +33,5 @@ RSpec.configure do |config|
33
33
  # order dependency and want to debug it, you can fix the order by providing
34
34
  # the seed, which is printed after each run.
35
35
  # --seed 1234
36
- config.order = "random"
36
+ config.order = 'random'
37
37
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Unit A" do
4
- it "should be true" do
5
- expect(true).to be_true
3
+ describe 'Unit A' do
4
+ it 'should be true' do
5
+ expect(true).to be true
6
6
  end
7
7
  end
@@ -1,7 +1,7 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Unit B" do
4
- it "should be true" do
5
- expect(true).to be_true
3
+ describe 'Unit B' do
4
+ it 'should be true' do
5
+ expect(true).to be true
6
6
  end
7
7
  end
@@ -1,61 +1,59 @@
1
- require "spec_helper"
2
-
3
- require_relative "../../../../lib/zeus/parallel_tests/worker"
1
+ require './lib/zeus/parallel_tests/worker'
4
2
 
5
3
  describe Zeus::ParallelTests::Worker do
6
- describe ".run" do
7
- let(:cli_argv) { ["rspec", "spec/models/model_spec.rb"] }
8
- let(:cli_env) { {"TEST_ENV_NUMBER" => "3"} }
9
- let(:worker) { double("worker", spawn: 0) }
10
- before { Zeus::ParallelTests::Worker.stub(new: worker) }
4
+ describe '.run' do
5
+ let(:cli_argv) { ['rspec', 'spec/models/model_spec.rb'] }
6
+ let(:cli_env) { { 'TEST_ENV_NUMBER' => '3' } }
7
+ let(:worker) { double('worker', spawn: 0) }
8
+ before { allow(Zeus::ParallelTests::Worker).to receive_messages(new: worker) }
11
9
  subject { Zeus::ParallelTests::Worker.run(cli_argv, cli_env) }
12
10
 
13
- it "creates instance of worker" do
14
- Zeus::ParallelTests::Worker.should_receive(:new)
15
- .with("rspec", cli_env, ["spec/models/model_spec.rb"])
11
+ it 'creates instance of worker' do
12
+ expect(Zeus::ParallelTests::Worker).to receive(:new)
13
+ .with('rspec', cli_env, ['spec/models/model_spec.rb'])
16
14
  .and_return(worker)
17
15
  subject
18
16
  end
19
17
 
20
- it "does not modify original env and argv" do
18
+ it 'does not modify original env and argv' do
21
19
  subject
22
- expect(cli_argv).to eq(["rspec", "spec/models/model_spec.rb"])
23
- expect(cli_env).to eq({"TEST_ENV_NUMBER" => "3"})
20
+ expect(cli_argv).to eq(['rspec', 'spec/models/model_spec.rb'])
21
+ expect(cli_env).to eq('TEST_ENV_NUMBER' => '3')
24
22
  end
25
23
 
26
- it "returns exit code" do
24
+ it 'returns exit code' do
27
25
  expect(subject).to eq(0)
28
26
  end
29
27
  end
30
28
 
31
- describe "#spawn" do
29
+ describe '#spawn' do
32
30
  subject { worker.spawn }
33
- let(:worker) { Zeus::ParallelTests::Worker.new("rspec", cli_env, ["spec/file_spec.rb"]) }
34
- let(:cli_env) { {"TEST_ENV_NUMBER" => 2, "PARALLEL_TEST_GROUPS" => 4} }
35
- let(:argv_file) { double("argv_file", path: "argv_file_path", unlink: true, puts: nil, close: nil) }
31
+ let(:worker) { Zeus::ParallelTests::Worker.new('rspec', cli_env, ['spec/file_spec.rb']) }
32
+ let(:cli_env) { { 'TEST_ENV_NUMBER' => 2, 'PARALLEL_TEST_GROUPS' => 4 } }
33
+ let(:argv_file) { double('argv_file', path: 'argv_file_path', unlink: true, puts: nil, close: nil) }
36
34
  before do
37
- Tempfile.stub(new: argv_file)
38
- worker.stub(system: true)
35
+ allow(Tempfile).to receive_messages(new: argv_file)
36
+ allow(worker).to receive_messages(system: true)
39
37
  end
40
38
 
41
- it "writes args to file" do
42
- argv_file.should_receive(:puts).with("spec/file_spec.rb")
39
+ it 'writes args to file' do
40
+ expect(argv_file).to receive(:puts).with('spec/file_spec.rb')
43
41
  subject
44
42
  end
45
43
 
46
- it "spawns worker and passes TEST_ENV_NUMBER, PARALLEL_TEST_GROUPS and argv file path" do
47
- worker.should_receive(:system).with("zeus parallel_rspec_worker 2 4 argv_file_path")
44
+ it 'spawns worker and passes TEST_ENV_NUMBER, PARALLEL_TEST_GROUPS and argv file path' do
45
+ expect(worker).to receive(:system).with('zeus parallel_rspec_worker 2 4 argv_file_path')
48
46
  subject
49
47
  end
50
48
 
51
- it "removes argv_file after run" do
52
- argv_file.should_receive(:unlink)
49
+ it 'removes argv_file after run' do
50
+ expect(argv_file).to receive(:unlink)
53
51
  subject
54
52
  end
55
53
 
56
- it "returns exit code" do
57
- system "true"
58
- worker.should_receive(:system) { $?.stub(to_i: 1) }
54
+ it 'returns exit code' do
55
+ system 'true'
56
+ expect(worker).to receive(:system) { allow($CHILD_STATUS).to receive_messages(to_i: 1) }
59
57
  expect(subject).to eq(1)
60
58
  end
61
59
  end
@@ -0,0 +1,56 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
2
+
3
+ require 'zeus/parallel_tests/version'
4
+ require 'open3'
5
+ require 'English'
6
+
7
+ describe 'zeus parallel spec' do
8
+ def launch_server
9
+ pid = fork do
10
+ Dir.chdir 'spec/dummy/' do
11
+ exec 'bundle exec zeus start > /dev/null'
12
+ end
13
+ end
14
+ sleep 3
15
+ pid
16
+ end
17
+
18
+ before(:all) do
19
+ # Copy current Appraisal gemfile to dummy app.
20
+ gemfile = File.read(ENV['BUNDLE_GEMFILE']).gsub(':path => "../"', ':path => "../../"')
21
+ File.open('spec/dummy/Gemfile', 'w+') { |f| f.write gemfile }
22
+ gemfile_lock = File.read("#{ENV['BUNDLE_GEMFILE']}.lock").gsub('remote: ../', 'remote: ../../')
23
+ File.open('spec/dummy/Gemfile.lock', 'w+') { |f| f.write gemfile_lock }
24
+
25
+ # Launch Zeus.
26
+ @server_pid = launch_server.to_s
27
+ end
28
+
29
+ it 'connects to server' do
30
+ Dir.chdir 'spec/dummy/' do
31
+ system('bundle', 'exec', 'zeus', 'r', 'true')
32
+ expect($CHILD_STATUS.success?).to be true
33
+ end
34
+ end
35
+
36
+ it 'runs rspec specs in two processes' do
37
+ Dir.chdir 'spec/dummy' do
38
+ Open3.popen2e('bundle', 'exec', 'zeus', 'parallel_rspec', '-n', '2', 'spec') do |_, output|
39
+ expect(output.to_a.map(&:chomp)).to include('2 processes for 2 specs, ~ 1 specs per process')
40
+ end
41
+ end
42
+ end
43
+
44
+ it 'runs cucumbers in two processes' do
45
+ Dir.chdir 'spec/dummy' do
46
+ Open3.popen2e('bundle', 'exec', 'zeus', 'parallel_cucumber', '-n', '2', 'features') do |_, output|
47
+ expect(output.to_a.map(&:chomp)).to include('2 processes for 2 features, ~ 1 features per process')
48
+ end
49
+ end
50
+ end
51
+
52
+ after(:all) do
53
+ system('kill', '-9', @server_pid)
54
+ system('rm', '-f', 'spec/dummy/Gemfile', 'spec/dummy/Gemfile.lock', 'spec/dummy/.zeus.sock')
55
+ end
56
+ end
@@ -1,14 +1,6 @@
1
- # This file was generated by the `rspec --init` command. Conventionally, all
2
- # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
- # Require this file using `require "spec_helper"` to ensure that it is only
4
- # loaded once.
5
- #
6
- # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
- RSpec.configure do |config|
8
- config.treat_symbols_as_metadata_keys_with_true_values = true
9
- config.run_all_when_everything_filtered = true
10
- config.filter_run :focus
1
+ require 'rspec'
11
2
 
3
+ RSpec.configure do |config|
12
4
  # Run specs in random order to surface order dependencies. If you find an
13
5
  # order dependency and want to debug it, you can fix the order by providing
14
6
  # the seed, which is printed after each run.
@@ -0,0 +1,16 @@
1
+ describe 'Configuration file generation' do
2
+ let(:project_dir) { File.expand_path(Dir.mktmpdir) }
3
+ let(:bin) { File.expand_path('../../bin/zeus-parallel_tests', __FILE__) }
4
+
5
+ subject { system(bin, 'init', chdir: project_dir) }
6
+
7
+ after { FileUtils.rm_rf project_dir }
8
+
9
+ it 'creates zeus configuration projects directory' do
10
+ subject
11
+
12
+ ['zeus.json', 'custom_plan.rb'].each do |f|
13
+ expect(File.exist?(File.join(project_dir, f))).to be_truthy
14
+ end
15
+ end
16
+ end
@@ -4,24 +4,33 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
  require 'zeus/parallel_tests/version'
5
5
 
6
6
  Gem::Specification.new do |spec|
7
- spec.name = "zeus-parallel_tests"
7
+ spec.name = 'zeus-parallel_tests'
8
8
  spec.version = Zeus::ParallelTests::VERSION
9
- spec.authors = ["Artur Roszczyk"]
10
- spec.email = ["artur.roszczyk@gmail.com"]
11
- spec.description = %q{Integration for zeus and parallel_tests}
12
- spec.summary = %q{}
13
- spec.homepage = ""
14
- spec.license = "MIT"
9
+ spec.authors = ['Artur Roszczyk']
10
+ spec.email = ['artur.roszczyk@gmail.com']
11
+ spec.description = 'Integration for zeus and parallel_tests'
12
+ spec.summary = ''
13
+ spec.homepage = ''
14
+ spec.license = 'MIT'
15
15
 
16
- spec.files = `git ls-files`.split($/)
16
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
17
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
19
+ spec.require_paths = ['lib']
20
20
 
21
- spec.add_dependency "zeus", "~> 0.13.3"
22
- spec.add_dependency "parallel_tests", ">= 0.11.3"
21
+ spec.add_dependency 'zeus', '>= 0.13.0'
22
+ spec.add_dependency 'parallel_tests', '>= 0.11.3'
23
23
 
24
- spec.add_development_dependency "bundler", "~> 1.3"
25
- spec.add_development_dependency "rake"
26
- spec.add_development_dependency "rspec"
24
+ spec.add_development_dependency 'appraisal'
25
+ spec.add_development_dependency 'bundler'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'rubocop'
28
+ spec.add_development_dependency 'rspec', '>= 3.0'
29
+
30
+ # Gems used by dummy app in testing.
31
+ spec.add_development_dependency 'cucumber-rails'
32
+ spec.add_development_dependency 'database_cleaner'
33
+ spec.add_development_dependency 'guard-rspec'
34
+ spec.add_development_dependency 'rspec-rails'
35
+ spec.add_development_dependency 'sqlite3'
27
36
  end