├── .document ├── .gitignore ├── .travis.yml ├── Gemfile ├── HISTORY ├── LICENSE ├── README.md ├── Rakefile ├── VERSION ├── features └── support │ └── env.rb ├── lib ├── sunspot_test.rb └── sunspot_test │ ├── cucumber.rb │ ├── rspec.rb │ └── test_unit.rb ├── spec ├── spec_helper.rb └── sunspot_test_spec.rb └── sunspot_test.gemspec /.document: -------------------------------------------------------------------------------- 1 | README.rdoc 2 | lib/**/*.rb 3 | bin/* 4 | features/**/*.feature 5 | LICENSE 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## MAC OS 2 | .DS_Store 3 | 4 | ## TEXTMATE 5 | *.tmproj 6 | tmtags 7 | 8 | ## EMACS 9 | *~ 10 | \#* 11 | .\#* 12 | 13 | ## VIM 14 | *.swp 15 | 16 | ## PROJECT::GENERAL 17 | coverage 18 | rdoc 19 | pkg 20 | Gemfile.lock 21 | 22 | ## PROJECT::SPECIFIC 23 | test_codebase 24 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | cache: bundler 3 | sudo: false 4 | rvm: 5 | - 1.9.3 6 | - 2.0 7 | - 2.1 8 | - 2.2 9 | - 2.3.1 10 | env: 11 | - CODECLIMATE_REPO_TOKEN=4cb98051f73c94aa1a3995c304d4a4adbb68fb1052c5e876e233c034fab9a226 12 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'http://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem "codeclimate-test-reporter", group: :test, require: nil 6 | -------------------------------------------------------------------------------- /HISTORY: -------------------------------------------------------------------------------- 1 | 0.4.0 - September 13, 2011 2 | * Added support for Test::Unit (thanks ordinaryzelig) 3 | * Fix to use an existing server (thanks mattscilipoti) 4 | 0.3.2 - August 4, 2011 5 | * Fixing bug where a server was launched multiple times (thanks aaronjenson and daniel-g) 6 | 0.3.1 - June 11, 2011 7 | * Renaming SunspotTestHelper to SunspotTest (thanks ersatzryan) 8 | * Enabling testing within rspec specs 9 | 0.2.0 - May 26, 2011 10 | * Moved requires from "sunspot_test" to "sunspot_test/cucumber" so we didn't conflict with bundler's autorequire. 11 | * Added non-@search functionality which stubs out the session and consequently speeds up the non-searching tests. 12 | * Added a configurable startup_timeout which defaults to 15 seconds. 13 | 0.1.2 - May 25, 2011 14 | * Wrote a more descriptive Readme for new users. 15 | 0.1.1 - May 18, 2011 16 | * Moved the repo to collectiveidea. 17 | 0.1.0 - May 18, 2011 18 | * Initial codebase to github. -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011 Zach Moazeni 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SunspotTest 2 | [![Gem Version](https://badge.fury.io/rb/sunspot_test.png)](http://badge.fury.io/rb/sunspot_test) 3 | [![Build Status](https://travis-ci.org/collectiveidea/sunspot_test.svg?branch=master)](https://travis-ci.org/collectiveidea/sunspot_test) 4 | [![Code Climate](https://codeclimate.com/github/collectiveidea/sunspot_test.png)](https://codeclimate.com/github/collectiveidea/sunspot_test) 5 | [![Coverage Status](https://codeclimate.com/github/collectiveidea/sunspot_test/coverage.png)](https://codeclimate.com/github/collectiveidea/sunspot_test/coverage.png) 6 | [![Dependency Status](https://gemnasium.com/collectiveidea/sunspot_test.svg)](https://gemnasium.com/collectiveidea/sunspot_test) 7 | 8 | ## How to install 9 | 10 | Install this sunspot_test from rubygems either directly: 11 | 12 | ```bash 13 | gem install sunspot_test 14 | ``` 15 | 16 | Or through bundler 17 | 18 | ```ruby 19 | # in Gemfile 20 | gem "sunspot_test" 21 | ``` 22 | 23 | Then in Cucumber's env.rb: 24 | 25 | ```ruby 26 | require 'sunspot_test/cucumber' 27 | ``` 28 | 29 | ## What does it do? 30 | 31 | This gem will automatically start and stop solr for cucumber tests when using the @search tag. For instance, if you have a searchable book model this will allow you to create/query/destroy books. 32 | 33 | ``` 34 | @search 35 | Feature: Books 36 | 37 | Scenario: Searching for a book 38 | Given a book exists with a title of "Of Mice and Men" 39 | ``` 40 | 41 | If your feature is not tagged with @search the environment will use a sunspot test proxy object which will silently swallow all requests. 42 | 43 | Starting solr will depend on your settings in `config/sunspot.yml` (though this configuration file is optional). If you run into issues remember to look for existing java processes, starting solr may conflict with existing instances. You can also check out http://collectiveidea.com/blog/archives/2011/05/25/testing-with-sunspot-and-cucumber/ which contains a little more information. 44 | 45 | ## Can it do RSpec? 46 | 47 | In `spec_helper.rb` 48 | 49 | ``` 50 | require 'sunspot_test/rspec' 51 | ``` 52 | 53 | Then within your specs, you'll need to tag and explicitly commit changes to solr: 54 | 55 | ```ruby 56 | require 'spec_helper' 57 | 58 | describe "searching", :search => true do 59 | it 'returns book results' do 60 | book = Factory(:book, :title => "Of Mice and Men") 61 | Sunspot.commit 62 | Book.search { keywords "mice"}.results.should == [book] 63 | end 64 | end 65 | ``` 66 | 67 | ## Can it do TestUnit? 68 | 69 | Same as RSpec. 70 | 71 | In `test_helper.rb` 72 | 73 | ```ruby 74 | require 'sunspot_test/test_unit' 75 | ``` 76 | 77 | Then within your test, you'll need to tag and explicitly commit changes to solr: 78 | 79 | ```ruby 80 | test 'searching' do 81 | book = Factory(:book, :title => "Of Mice and Men") 82 | Sunspot.commit 83 | assert_equal [book], Book.search { keywords "mice"}.results 84 | end 85 | ``` 86 | 87 | ## Configuring the timeout 88 | 89 | The test suite will try and launch a solr process and wait for 15 seconds for the process to launch. You can configure this timeout by setting the following in env.rb: 90 | 91 | ```ruby 92 | SunspotTest.solr_startup_timeout = 60 # will wait 60 seconds for the solr process to start 93 | ``` 94 | 95 | ## Note on Patches/Pull Requests 96 | 97 | * Fork the project. 98 | * Make your feature addition or bug fix. 99 | future version unintentionally. 100 | * Commit, do not mess with rakefile, version, or history. 101 | (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull) 102 | * Send me a pull request. Bonus points for topic branches. 103 | 104 | ## Copyright 105 | 106 | Copyright (c) 2011 Zach Moazeni. See LICENSE for details. 107 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require 'rspec/core/rake_task' 3 | 4 | RSpec::Core::RakeTask.new(:spec) 5 | 6 | task :default => :spec 7 | -------------------------------------------------------------------------------- /VERSION: -------------------------------------------------------------------------------- 1 | 0.4.2 -------------------------------------------------------------------------------- /features/support/env.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib') 2 | require 'something_test' 3 | 4 | require 'spec/expectations' 5 | -------------------------------------------------------------------------------- /lib/sunspot_test.rb: -------------------------------------------------------------------------------- 1 | require 'sunspot/rails' 2 | require 'net/http' 3 | 4 | module SunspotTest 5 | class TimeOutError < StandardError; end; 6 | class << self 7 | 8 | attr_writer :solr_startup_timeout 9 | attr_writer :server 10 | 11 | def solr_startup_timeout 12 | @solr_startup_timeout || 15 13 | end 14 | 15 | def setup_solr 16 | unstub 17 | start_sunspot_server 18 | end 19 | 20 | def server 21 | @server ||= Sunspot::Rails::Server.new 22 | end 23 | 24 | def start_sunspot_server 25 | unless solr_running? 26 | pid = fork do 27 | STDERR.reopen("/dev/null") 28 | STDOUT.reopen("/dev/null") 29 | server.run 30 | end 31 | 32 | at_exit { Process.kill("TERM", pid) } 33 | 34 | wait_until_solr_starts 35 | end 36 | end 37 | 38 | # Stubs Sunspot calls to Solr server 39 | def stub 40 | unless @session_stubbed 41 | Sunspot.session = Sunspot::Rails::StubSessionProxy.new(original_sunspot_session) 42 | @session_stubbed = true 43 | end 44 | end 45 | 46 | # Resets Sunspot to call Solr server, opposite of stub 47 | def unstub 48 | if @session_stubbed 49 | Sunspot.session = original_sunspot_session 50 | @session_stubbed = false 51 | end 52 | end 53 | 54 | private 55 | 56 | def original_sunspot_session 57 | @original_sunspot_session ||= Sunspot.session 58 | end 59 | 60 | def wait_until_solr_starts 61 | (solr_startup_timeout * 10).times do 62 | break if solr_running? 63 | sleep(0.1) 64 | end 65 | raise TimeOutError, "Solr failed to start after #{solr_startup_timeout} seconds" unless solr_running? 66 | end 67 | 68 | def solr_running? 69 | begin 70 | solr_ping_uri = URI.parse("#{Sunspot.session.config.solr.url}/ping") 71 | res = Net::HTTP.get_response(solr_ping_uri) 72 | # Solr will return 503 codes when it's starting up 73 | res.code != '503' 74 | rescue 75 | false # Solr Not Running 76 | end 77 | end 78 | end 79 | end 80 | -------------------------------------------------------------------------------- /lib/sunspot_test/cucumber.rb: -------------------------------------------------------------------------------- 1 | require 'sunspot_test' 2 | 3 | Before("@searchrunning") do 4 | $sunspot = true 5 | end 6 | 7 | # Old-style tag expressions were deprecated in cucumber 3.0.0.pre.2, and removed in 4.0.0.rc.1: 8 | # https://github.com/cucumber/cucumber-ruby/blob/master/CHANGELOG.md#300pre2 9 | # https://github.com/cucumber/cucumber-ruby/blob/master/CHANGELOG.md#400rc1-2018-09-29 10 | negated_tag_prefix = 11 | if defined?(Cucumber::VERSION) && Gem::Version.new(Cucumber::VERSION) >= Gem::Version.new('3') 12 | "not " 13 | else 14 | "~" 15 | end 16 | 17 | Before("#{negated_tag_prefix}@search") do 18 | SunspotTest.stub 19 | end 20 | 21 | Before("@search") do 22 | SunspotTest.setup_solr 23 | Sunspot.remove_all! 24 | Sunspot.commit 25 | end 26 | 27 | AfterStep('@search') do 28 | Sunspot.commit 29 | end 30 | -------------------------------------------------------------------------------- /lib/sunspot_test/rspec.rb: -------------------------------------------------------------------------------- 1 | require 'sunspot_test' 2 | 3 | RSpec.configure do |c| 4 | c.before(:each) do 5 | SunspotTest.stub 6 | end 7 | 8 | c.before(:each, :search => true) do 9 | SunspotTest.setup_solr 10 | Sunspot.remove_all! 11 | Sunspot.commit 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /lib/sunspot_test/test_unit.rb: -------------------------------------------------------------------------------- 1 | SunspotTest.stub 2 | SunspotTest.setup_solr 3 | Sunspot.remove_all! 4 | Sunspot.commit 5 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | $LOAD_PATH.unshift(File.dirname(__FILE__)) 2 | $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib')) 3 | 4 | require 'sunspot' 5 | require 'sunspot_test' 6 | -------------------------------------------------------------------------------- /spec/sunspot_test_spec.rb: -------------------------------------------------------------------------------- 1 | require "spec_helper" 2 | 3 | describe SunspotTest do 4 | describe ".solr_startup_timeout" do 5 | after(:all) { SunspotTest.solr_startup_timeout = 15 } 6 | 7 | it "defaults to 15" do 8 | expect(SunspotTest.solr_startup_timeout).to eq(15) 9 | end 10 | 11 | it "can be set using .solr_startup_timeout=" do 12 | SunspotTest.solr_startup_timeout = 20 13 | expect(SunspotTest.solr_startup_timeout).to eq(20) 14 | end 15 | end 16 | 17 | describe "setup_solr" do 18 | it "calls unstub and start_sunspot_server" do 19 | expect(SunspotTest).to receive(:unstub) 20 | expect(SunspotTest).to receive(:start_sunspot_server) 21 | SunspotTest.setup_solr 22 | end 23 | end 24 | 25 | describe "server" do 26 | it "creates a new Sunspot Rails Server" do 27 | expect(Sunspot::Rails::Server).to receive(:new) 28 | SunspotTest.server 29 | end 30 | end 31 | 32 | describe ".start_sunspot_server" do 33 | context "if server is already started" do 34 | before do 35 | allow(SunspotTest).to receive(:solr_running?) { true } 36 | end 37 | 38 | it "does not try to spin up another server" do 39 | expect(Kernel).not_to receive(:fork) 40 | SunspotTest.start_sunspot_server 41 | end 42 | end 43 | 44 | context "if the server has NOT been started" do 45 | before do 46 | allow(SunspotTest).to receive(:wait_until_solr_starts) { true } 47 | end 48 | 49 | before do 50 | SunspotTest.server = nil 51 | 52 | fake_server = double("server") 53 | allow(SunspotTest).to receive(:server) { fake_server } 54 | end 55 | 56 | # was getting funky issues when the test was broken up 57 | it "forks the process, redirects stdout/stderr, runs server, sets exit hook, waits for server" do 58 | 59 | expect(SunspotTest).to receive(:fork) do |&block| 60 | expect(STDERR).to receive(:reopen).with("/dev/null") 61 | expect(STDOUT).to receive(:reopen).with("/dev/null") 62 | expect(SunspotTest.server).to receive(:run) 63 | block.call 64 | end 65 | 66 | expect(SunspotTest).to receive(:at_exit) do |&block| 67 | expect(Process).to receive(:kill) 68 | block.call 69 | end 70 | 71 | expect(SunspotTest).to receive(:wait_until_solr_starts) 72 | SunspotTest.start_sunspot_server 73 | end 74 | end 75 | 76 | describe ".stub" do 77 | context "if the session is already stubbed" do 78 | before do 79 | SunspotTest.instance_variable_set(:@session_stubbed, true) 80 | end 81 | 82 | it "does nothing" do 83 | expect(Sunspot::Rails::StubSessionProxy).not_to receive(:new) 84 | 85 | SunspotTest.stub 86 | end 87 | end 88 | 89 | context "if the session is not currently stubbed" do 90 | before do 91 | SunspotTest.instance_variable_set(:@session_stubbed, false) 92 | end 93 | 94 | it "stubs the Sunspot session and sets @session_stubbed to true" do 95 | expect(Sunspot::Rails::StubSessionProxy).to receive(:new) 96 | 97 | SunspotTest.stub 98 | end 99 | 100 | it "sets @session_stubbed to true" do 101 | SunspotTest.stub 102 | expect(SunspotTest.instance_variable_get(:@session_stubbed)).to eq(true) 103 | end 104 | end 105 | end 106 | 107 | describe ".unstub" do 108 | context "if the session is not stubbed" do 109 | before do 110 | SunspotTest.instance_variable_set(:@session_stubbed, false) 111 | end 112 | it "does nothing" do 113 | expect(SunspotTest).not_to receive(:original_sunspot_session) 114 | SunspotTest.unstub 115 | end 116 | end 117 | 118 | context "if the session is currently stubbed" do 119 | before do 120 | SunspotTest.instance_variable_set(:@session_stubbed, true) 121 | end 122 | 123 | it "sets the Sunspot session to the original session" do 124 | expect(SunspotTest).to receive(:original_sunspot_session) 125 | 126 | SunspotTest.unstub 127 | end 128 | 129 | it "sets @session_stubbed to true" do 130 | SunspotTest.unstub 131 | expect(SunspotTest.instance_variable_get(:@session_stubbed)).to eq(false) 132 | end 133 | end 134 | end 135 | 136 | describe ".solr_running" do 137 | context "if solr is running" do 138 | before do 139 | Net::HTTP.stub(get_response: double(code: '200')) 140 | end 141 | 142 | it "returns true" do 143 | expect(SunspotTest.send(:solr_running?)).to eq(true) 144 | end 145 | end 146 | 147 | context "if solr is not running" do 148 | it "returns false" do 149 | expect(SunspotTest.send(:solr_running?)).to eq(false) 150 | end 151 | end 152 | 153 | context "if solr is starting up" do 154 | before do 155 | Net::HTTP.stub(get_response:double(code: '503')) 156 | end 157 | 158 | it "returns false" do 159 | expect(SunspotTest.send(:solr_running?)).to eq(false) 160 | end 161 | end 162 | 163 | end 164 | 165 | describe ".wait_until_solr_starts" do 166 | context "if solr never starts" do 167 | before do 168 | SunspotTest.solr_startup_timeout = 2 169 | end 170 | 171 | it "calls solr_running? until solr_startup_timeout raises TimeOutError" do 172 | expect(SunspotTest).to receive(:solr_running?).exactly((SunspotTest.solr_startup_timeout * 10) + 1).times 173 | 174 | expect { SunspotTest.send(:wait_until_solr_starts) } 175 | .to raise_error SunspotTest::TimeOutError, "Solr failed to start after #{SunspotTest.solr_startup_timeout} seconds" 176 | end 177 | end 178 | 179 | context "if solr is started" do 180 | it "calls solr_running? and returns" do 181 | expect(SunspotTest).to receive(:solr_running?).exactly(2).times.and_return(true) 182 | 183 | expect { SunspotTest.send(:wait_until_solr_starts) } 184 | .not_to raise_error 185 | end 186 | end 187 | end 188 | end 189 | end 190 | -------------------------------------------------------------------------------- /sunspot_test.gemspec: -------------------------------------------------------------------------------- 1 | # encoding: utf-8 2 | # 3 | Gem::Specification.new do |s| 4 | s.name = "sunspot_test" 5 | s.version = "0.4.2" 6 | 7 | s.authors = ["Zach Moazeni"] 8 | s.email = "zach@collectiveidea.com" 9 | s.description = "Testing sunspot with cucumber can be a pain. This gem will automatically start/stop solr with cucumber scenarios tagged with @search" 10 | s.summary = "Auto-starts solr for your cucumber tests" 11 | s.homepage = "https://github.com/collectiveidea/sunspot_test" 12 | s.license = "MIT" 13 | 14 | s.files = `git ls-files`.split($/) 15 | s.test_files = s.files.grep(/^spec/) 16 | s.require_paths = ["lib"] 17 | 18 | s.add_runtime_dependency "sunspot_solr" 19 | s.add_runtime_dependency "sunspot_rails", ">= 2.1.1" 20 | 21 | s.add_development_dependency "bundler" 22 | s.add_development_dependency "rake" 23 | s.add_development_dependency "rspec" 24 | end 25 | 26 | --------------------------------------------------------------------------------