├── .gitignore ├── .rspec ├── .travis.yml ├── CHANGELOG.md ├── Gemfile ├── Guardfile ├── LICENSE ├── README.md ├── Rakefile ├── guard-test.gemspec ├── lib └── guard │ ├── test.rb │ └── test │ ├── guard_test_runner.rb │ ├── inspector.rb │ ├── notifier.rb │ ├── runner.rb │ ├── templates │ └── Guardfile │ └── version.rb ├── spec ├── lib │ └── guard │ │ ├── test │ │ ├── inspector_spec.rb │ │ ├── notifier_spec.rb │ │ └── runner_spec.rb │ │ └── test_spec.rb └── spec_helper.rb └── test ├── succeeding_test.rb ├── succeeding_tests.rb ├── test_helper.rb ├── test_old.rb └── unit ├── error └── error_test.rb └── failing_test.rb /.gitignore: -------------------------------------------------------------------------------- 1 | pkg/* 2 | *.gem 3 | .bundle 4 | .DS_Store 5 | .rvmrc 6 | .rbx/* 7 | Gemfile.lock 8 | coverage/ 9 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --fail-fast 2 | --format documentation 3 | --color 4 | --require spec_helper 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | cache: bundler 3 | rvm: 4 | - 2.1 5 | - 2.2 6 | - 2.3.0 7 | - jruby-19mode 8 | - rbx-2 9 | addons: 10 | code_climate: 11 | repo_token: c2fc6d91a4f61b11207fc145b35c379fc6b3514c74f2a53905dd4d21405332d8 12 | sudo: false 13 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Moved to [GitHub releases](https://github.com/guard/guard-test/releases) page. 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | gemspec 4 | 5 | gem 'rake' 6 | 7 | group :development do 8 | gem 'ruby_gntp' 9 | gem 'guard-rspec' 10 | end 11 | 12 | # The test group will be 13 | # installed on Travis CI 14 | # 15 | group :test do 16 | gem 'rspec', '~> 3.1' 17 | gem 'codeclimate-test-reporter', require: nil 18 | end 19 | 20 | platforms :rbx do 21 | gem 'racc' 22 | gem 'rubysl', '~> 2.0' 23 | gem 'psych' 24 | end 25 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | group :specs, halt_on_fail: true do 2 | guard :rspec, cmd: 'bundle exec rspec', failed_mode: :keep do 3 | require "guard/rspec/dsl" 4 | dsl = Guard::RSpec::Dsl.new(self) 5 | 6 | # Feel free to open issues for suggestions and improvements 7 | 8 | # RSpec files 9 | rspec = dsl.rspec 10 | watch(rspec.spec_helper) { rspec.spec_dir } 11 | watch(rspec.spec_support) { rspec.spec_dir } 12 | watch(rspec.spec_files) 13 | 14 | # Ruby files 15 | ruby = dsl.ruby 16 | dsl.watch_spec_files_for(ruby.lib_files) 17 | end 18 | end 19 | 20 | group :tests do 21 | guard :test do 22 | watch(%r{test/.+_test\.rb}) 23 | watch('test/test_helper.rb') { "test" } 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2010-2015 Rémy Coutable 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 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | :exclamation: [Guard::Minitest](https://github.com/guard/guard-minitest) is a better alternative to Guard::Test, you should definitely check it out: https://github.com/guard/guard-minitest. :exclamation: 2 | 3 | # Guard::Test 4 | 5 | [![Gem Version](https://img.shields.io/gem/v/guard-test.svg?style=flat)](https://rubygems.org/gems/guard-test) [![Build Status](https://travis-ci.org/guard/guard-test.svg?branch=master)](https://travis-ci.org/guard/guard-test) [![Dependency Status](https://gemnasium.com/guard/guard-test.svg)](https://gemnasium.com/guard/guard-test) [![Code Climate](https://codeclimate.com/github/guard/guard-test/badges/gpa.svg)](https://codeclimate.com/github/guard/guard-test) [![Test Coverage](https://codeclimate.com/github/guard/guard-test/badges/coverage.svg)](https://codeclimate.com/github/guard/guard-test) 6 | 7 | Guard::Test allows to automatically & intelligently launch tests when you create or modify files. 8 | 9 | * Compatible with Test::Unit 2. 10 | * Tested against Ruby 2.1, 2.2, Rubinius & JRuby (1.9 mode only). 11 | 12 | ## Install 13 | 14 | Please be sure to have [Guard](https://github.com/guard/guard) installed before continuing. 15 | 16 | Add the gem to your Gemfile (inside the `:development` or `:tool` group): 17 | 18 | ``` ruby 19 | group :development do 20 | gem 'guard-test' 21 | end 22 | ``` 23 | 24 | Add guard definition to your Guardfile by running this command: 25 | 26 | ``` bash 27 | $ guard init test 28 | ``` 29 | 30 | ## Ruby on Rails 31 | 32 | Ruby on Rails lazy loads gems as needed in its test suite. 33 | As a result Guard::Test may not be able to run all tests until the gem dependencies are resolved. 34 | 35 | To solve the issue either add the missing dependencies or remove the tests. 36 | 37 | Example: 38 | 39 | ``` 40 | Specify ruby-prof as application's dependency in Gemfile to run benchmarks. 41 | ``` 42 | 43 | Rails automatically generates a performance test stub in the `test/performance` directory which can trigger this error. 44 | Either add `ruby-prof` to your `Gemfile` (inside the `test` group): 45 | 46 | ``` ruby 47 | group :test do 48 | gem 'ruby-prof' 49 | end 50 | ``` 51 | 52 | Or remove the test if it isn't necessary. 53 | 54 | ## Usage 55 | 56 | Please read the [Guard usage doc](https://github.com/guard/guard#readme). 57 | 58 | By default, Guard::Test watch for files matching `test_*.rb` or `*_test{s,}.rb` in the `test` directory (you can change this directory with the `test_paths` option, see below). 59 | 60 | ## Guardfile 61 | 62 | See the [template Guardfile](https://github.com/guard/guard-test/blob/master/lib/guard/test/templates/Guardfile) for some examples. 63 | 64 | Please read the [Guard documentation](https://github.com/guard/guard#readme) for more info about the Guardfile DSL. 65 | 66 | ## Options 67 | 68 | **Deprecation notice:** The `:runner` option is deprecated. If you had set it to "fastfail", it is now the default in test-unit 2, but if you want the opposite, you can pass the `cli: '--no-show-detail-immediately'` option instead. 69 | 70 | ### Available options 71 | 72 | ``` ruby 73 | bundler: false # Whether or not to use `bundle exec` to run tests, default: true (if a you have a Gemfile in the current directory) 74 | rubygems: true # Whether or not to require rubygems (if bundler isn't used) when running the tests, default: false 75 | rvm: ['1.9.3', 'jruby'] # Directly run your specs against multiple Rubies, default: nil 76 | spring: true # Run your tests with [`spring`](https://github.com/jonleighton/spring), default: false 77 | zeus: true # Run your tests with [`zeus`](https://github.com/burke/zeus), default: false 78 | drb: true # Run your tests with [`spork-testunit`](https://github.com/timcharper/spork-testunit), default: false 79 | include: ['foo', 'bar'] # Pass arbitrary include paths to the command that runs the tests, default: ['test'] 80 | cli: 'color' # Pass arbitrary CLI arguments to the command that runs the tests, default: nil 81 | all_on_start: false # Run all tests on Guard startup, default: true. 82 | all_after_pass: false # Run all tests after the current run tests pass, default: true 83 | keep_failed: false # Re-run failing tests until they pass, default: true 84 | test_paths: ['spec'] # Array of paths that where are located the test files, default: ['test'] 85 | ``` 86 | 87 | #### `spring` option 88 | 89 | **Important:** The `spring testunit` command of official version 0.0.8 of spring is running only file specified as first argument, other are ignored. Fortunately this issue has been fixed recently in spring master and all test files given in arguments are invoked, see [#102](https://github.com/jonleighton/spring/pull/102). However that has not been packaged yet, therefore while waiting for spring 0.0.9 release we recommend to use (in your Gemfile): 90 | 91 | ```ruby 92 | gem 'spring', github: 'jonleighton/spring' 93 | ``` 94 | 95 | #### `zeus` option 96 | 97 | When true, the `include` option is disregarded, as it does not work with `zeus`' test runner. 98 | 99 | The zeus server process (`zeus start`) must already be running in another terminal (you can use [guard-zeus](http://rubygems.org/gems/guard-zeus) for that). 100 | 101 | #### `drb` option 102 | 103 | When true, notifications are disabled. This might be fixed in future releases. 104 | 105 | ## Development 106 | 107 | * Documentation hosted at [RubyDoc](http://rubydoc.info/gems/guard-test/frames). 108 | * Source hosted at [GitHub](https://github.com/guard/guard-test). 109 | 110 | Pull requests are very welcome! Please try to follow these simple rules if applicable: 111 | 112 | * Please create a topic branch for every separate change you make. 113 | * Make sure your patches are well tested. All specs must pass on [Travis CI](https://travis-ci.org/guard/guard-test). 114 | * Update the [Yard](http://yardoc.org/) documentation. 115 | * Update the [README](https://github.com/guard/guard-test/blob/master/README.md). 116 | * Please **do not change** the version number. 117 | 118 | For questions please join us in our [Google group](http://groups.google.com/group/guard-dev) or on 119 | `#guard` (irc.freenode.net). 120 | 121 | ## Author 122 | 123 | [Rémy Coutable](https://github.com/rymai) 124 | 125 | ## Contributors 126 | 127 | [https://github.com/guard/guard-test/graphs/contributors](https://github.com/guard/guard-test/graphs/contributors) 128 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require 'bundler/gem_tasks' 2 | 3 | require 'rspec/core/rake_task' 4 | RSpec::Core::RakeTask.new(:spec) do |t| 5 | t.verbose = (ENV['CI'] == 'true') 6 | end 7 | 8 | task default: :spec 9 | -------------------------------------------------------------------------------- /guard-test.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path('../lib', __FILE__) 2 | require 'guard/test/version' 3 | 4 | Gem::Specification.new do |s| 5 | s.name = 'guard-test' 6 | s.version = Guard::TestVersion::VERSION 7 | s.platform = Gem::Platform::RUBY 8 | s.license = 'MIT' 9 | s.author = 'Rémy Coutable' 10 | s.email = 'remy@rymai.me' 11 | s.homepage = 'https://rubygems.org/gems/guard-test' 12 | s.summary = 'Guard plugin for Test::Unit 2' 13 | s.description = 'Guard::Test automatically run your tests on file modification.' 14 | 15 | s.required_ruby_version = '>= 1.9.2' 16 | 17 | s.add_runtime_dependency 'test-unit', '~> 3.0' 18 | s.add_runtime_dependency 'guard-compat', '~> 1.2' 19 | 20 | s.add_development_dependency 'bundler', '~> 1.6' 21 | 22 | s.files = Dir.glob('{lib}/**/*') + %w[CHANGELOG.md LICENSE README.md] 23 | s.require_path = 'lib' 24 | end 25 | -------------------------------------------------------------------------------- /lib/guard/test.rb: -------------------------------------------------------------------------------- 1 | require 'guard/compat/plugin' 2 | require 'guard/test/version' 3 | require 'test/unit/version' 4 | 5 | module Guard 6 | class Test < Plugin 7 | 8 | require 'guard/test/runner' 9 | require 'guard/test/inspector' 10 | 11 | def initialize(options = {}) 12 | super 13 | @options = { 14 | all_on_start: true, 15 | all_after_pass: true, 16 | keep_failed: true, 17 | test_paths: ['test'] 18 | }.update(options) 19 | @last_failed = false 20 | @failed_paths = [] 21 | 22 | @runner = Runner.new(options) 23 | end 24 | 25 | def start 26 | Compat::UI.info("Guard::Test #{TestVersion::VERSION} is running, " + 27 | "with Test::Unit #{::Test::Unit::VERSION}!", reset: true) 28 | run_all if @options[:all_on_start] 29 | end 30 | 31 | def run_all 32 | Inspector.test_paths = @options[:test_paths] 33 | test_paths = @options[:test_paths].clone # because clean - cleaning variable 34 | passed = @runner.run(Inspector.clean(test_paths), message: 'Running all tests') 35 | 36 | @failed_paths = [] if passed 37 | @last_failed = !passed 38 | end 39 | 40 | def reload 41 | @failed_paths = [] 42 | end 43 | 44 | def run_on_modifications(paths) 45 | Inspector.test_paths = @options[:test_paths] 46 | paths += @failed_paths if @options[:keep_failed] 47 | paths = Inspector.clean(paths) 48 | passed = @runner.run(paths) 49 | 50 | if passed 51 | # clean failed paths memory 52 | @failed_paths -= paths if @options[:keep_failed] 53 | 54 | # run all the tests if the changed tests failed, like autotest 55 | run_all if @last_failed && @options[:all_after_pass] 56 | else 57 | # remember failed paths for the next change 58 | @failed_paths += paths if @options[:keep_failed] 59 | 60 | # track whether the changed tests failed for the next change 61 | @last_failed = true 62 | end 63 | end 64 | 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /lib/guard/test/guard_test_runner.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit/autorunner' 2 | require 'test/unit/ui/console/testrunner' 3 | require 'guard/test/notifier' 4 | 5 | # Thanks to Adam Sanderson for the really good starting point: 6 | # http://endofline.wordpress.com/2008/02/11/a-custom-testrunner-to-scratch-an-itch/ 7 | # 8 | # This class inherits from Test::Unit' standard console TestRunner 9 | # I'm just overriding some callbacks methods to strip some outputs and display a notification on end 10 | class GuardTestRunner < ::Test::Unit::UI::Console::TestRunner 11 | 12 | def initialize(suite, options = {}) 13 | super 14 | @color_scheme["pass"] = ::Test::Unit::Color.new("green", foreground: true, bold: true) 15 | @color_scheme["failure"] = ::Test::Unit::Color.new("red", foreground: true, bold: true) 16 | end 17 | 18 | protected 19 | 20 | # Test::Unit::UI::Console::TestRunner overrided methods 21 | def setup_mediator 22 | @mediator = ::Test::Unit::UI::TestRunnerMediator.new(@suite) 23 | end 24 | 25 | def finished(elapsed_time) 26 | super 27 | ::Guard::Test::Notifier.notify(@result, elapsed_time) 28 | nl 29 | end 30 | 31 | def fault_color_name(fault) 32 | fault.class.name.split(/::/).last.downcase.to_sym 33 | end 34 | 35 | end 36 | 37 | Test::Unit::AutoRunner.register_runner(:guard_test) { |r| GuardTestRunner } 38 | -------------------------------------------------------------------------------- /lib/guard/test/inspector.rb: -------------------------------------------------------------------------------- 1 | require 'guard/compat/plugin' 2 | 3 | module Guard 4 | class Test < Plugin 5 | module Inspector 6 | 7 | class << self 8 | def test_paths 9 | @test_paths || [] 10 | end 11 | 12 | def test_paths=(path_array) 13 | @test_paths = Array(path_array) 14 | end 15 | 16 | def clean(paths) 17 | paths.uniq! 18 | paths.compact! 19 | 20 | paths.dup.each do |path| 21 | if test_folder?(path) 22 | paths.delete(path) 23 | paths += check_test_files(path) 24 | else 25 | paths.delete(path) unless test_file?(path) 26 | end 27 | end 28 | 29 | paths.uniq! 30 | paths.compact! 31 | clear_test_files_list 32 | paths.sort - ['test/test_helper.rb'] 33 | end 34 | 35 | private 36 | 37 | def test_folder?(path) 38 | paths = test_paths.join("|") 39 | path.match(%r{^\/?(#{paths})}) && !path.match(/\..+$/) && File.directory?(path) 40 | end 41 | 42 | def test_file?(path) 43 | test_files.include?(path) 44 | end 45 | 46 | def test_files 47 | @test_files ||= test_paths.collect { |path| check_test_files(path) }.flatten 48 | end 49 | 50 | def clear_test_files_list 51 | @test_files = nil 52 | end 53 | 54 | def check_test_files(path) 55 | Dir[File.join(path, '**', 'test_*.rb')] + 56 | Dir[File.join(path, '**', '*_test{s,}.rb')] 57 | end 58 | end 59 | 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /lib/guard/test/notifier.rb: -------------------------------------------------------------------------------- 1 | require 'guard/compat/plugin' 2 | 3 | module Guard 4 | class Test < Plugin 5 | module Notifier 6 | 7 | class << self 8 | def notify(result, elapsed_time) 9 | Compat::UI.notify( 10 | summary(result) + "\n\n" + duration(elapsed_time), 11 | title: "Test::Unit results", 12 | image: result.passed? ? :success : :failed 13 | ) 14 | end 15 | 16 | private 17 | 18 | def summary(result) 19 | "#{result.run_count} test#{'s' if result.run_count != 1}, " + 20 | "#{result.assertion_count} assert#{'s' if result.assertion_count != 1}, " + 21 | "#{result.failure_count} fail#{'s' if result.failure_count != 1}, " + 22 | "#{result.error_count} error#{'s' if result.error_count != 1}" 23 | end 24 | 25 | def duration(duration, options = {}) 26 | "Finished in #{round_float(duration)} seconds" 27 | end 28 | 29 | def round_float(float, decimals = 4) 30 | if Float.instance_method(:round).arity == 0 # Ruby 1.8 31 | factor = 10**decimals 32 | (float*factor).round / factor.to_f 33 | else # Ruby 1.9 34 | float.round(decimals) 35 | end 36 | end 37 | end 38 | 39 | end 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /lib/guard/test/runner.rb: -------------------------------------------------------------------------------- 1 | require 'guard/compat/plugin' 2 | 3 | module Guard 4 | class Test < Plugin 5 | class Runner 6 | 7 | attr_reader :options 8 | 9 | def initialize(opts = {}) 10 | @options = { 11 | bundler: File.exist?("#{Dir.pwd}/Gemfile"), 12 | rubygems: false, 13 | rvm: [], 14 | include: %w[lib:test], 15 | drb: false, 16 | zeus: false, 17 | spring: false, 18 | cli: '' 19 | }.merge(opts) 20 | end 21 | 22 | def run(paths, opts = {}) 23 | return true if paths.empty? 24 | 25 | Compat::UI.info(opts[:message] || "Running: #{paths.join(' ')}", reset: true) 26 | 27 | system(test_unit_command(paths)) 28 | end 29 | 30 | def bundler? 31 | if @bundler.nil? 32 | @bundler = options[:bundler] && !drb? && !zeus? && !spring? 33 | end 34 | @bundler 35 | end 36 | 37 | def rubygems? 38 | !bundler? && !zeus? && !spring? && options[:rubygems] 39 | end 40 | 41 | def drb? 42 | if @drb.nil? 43 | @drb = options[:drb] 44 | begin 45 | require 'spork-testunit' 46 | rescue LoadError 47 | end 48 | Compat::UI.info('Using testdrb to run the tests') if @drb 49 | end 50 | @drb 51 | end 52 | 53 | def zeus? 54 | if @zeus.nil? 55 | @zeus = options[:zeus] 56 | Compat::UI.info('Using zeus to run the tests') if @zeus 57 | end 58 | @zeus 59 | end 60 | 61 | def spring? 62 | if @spring.nil? 63 | @spring = options[:spring] 64 | Compat::UI.info('Using spring to run the tests') if @spring 65 | end 66 | @spring 67 | end 68 | 69 | private 70 | 71 | def test_unit_command(paths) 72 | cmd_parts = executables 73 | cmd_parts.concat(includes_and_requires(paths)) 74 | cmd_parts.concat(command_options) 75 | cmd_parts << options[:cli] 76 | 77 | cmd_parts.compact.join(' ').strip 78 | end 79 | 80 | def executables 81 | parts = [] 82 | parts << "rvm #{options[:rvm].join(',')} exec" unless options[:rvm].empty? 83 | parts << 'bundle exec' if bundler? 84 | parts << case true 85 | when drb? then 'testdrb' 86 | when zeus? then 'zeus test' 87 | when spring? then spring_command 88 | else 'ruby'; end 89 | end 90 | 91 | def spring_command 92 | if Gem.loaded_specs["rails"] && Gem.loaded_specs["rails"].version < Gem::Version.create('4.0') 93 | 'spring testunit' 94 | else 95 | # rails > 4.0 supports passing a path to rake test 96 | 'spring rake test' 97 | end 98 | end 99 | 100 | def includes_and_requires(paths) 101 | parts = [] 102 | parts << Array(options[:include]).map { |path| "-I\"#{path}\"" } unless zeus? || spring? 103 | parts << paths if zeus? || spring? || drb? 104 | parts << '-r bundler/setup' if bundler? 105 | parts << '-r rubygems' if rubygems? 106 | 107 | unless drb? || zeus? || spring? 108 | parts << "-r #{File.expand_path("../guard_test_runner", __FILE__)}" 109 | parts << "-e \"%w[#{paths.join(' ')}].each { |p| load p }\"" 110 | end 111 | 112 | parts 113 | end 114 | 115 | def command_options 116 | if drb? || zeus? || spring? 117 | [] 118 | else 119 | ['--', '--use-color', '--runner=guard_test'] 120 | end 121 | end 122 | 123 | end 124 | end 125 | end 126 | -------------------------------------------------------------------------------- /lib/guard/test/templates/Guardfile: -------------------------------------------------------------------------------- 1 | guard :test do 2 | watch(%r{^test/.+_test\.rb$}) 3 | watch('test/test_helper.rb') { 'test' } 4 | 5 | # Non-rails 6 | watch(%r{^lib/(.+)\.rb$}) { |m| "test/#{m[1]}_test.rb" } 7 | 8 | # Rails 4 9 | # watch(%r{^app/(.+)\.rb}) { |m| "test/#{m[1]}_test.rb" } 10 | # watch(%r{^app/controllers/application_controller\.rb}) { 'test/controllers' } 11 | # watch(%r{^app/controllers/(.+)_controller\.rb}) { |m| "test/integration/#{m[1]}_test.rb" } 12 | # watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" } 13 | # watch(%r{^lib/(.+)\.rb}) { |m| "test/lib/#{m[1]}_test.rb" } 14 | 15 | # Rails < 4 16 | # watch(%r{^app/models/(.+)\.rb$}) { |m| "test/unit/#{m[1]}_test.rb" } 17 | # watch(%r{^app/controllers/(.+)\.rb$}) { |m| "test/functional/#{m[1]}_test.rb" } 18 | # watch(%r{^app/views/(.+)/.+\.erb$}) { |m| "test/functional/#{m[1]}_controller_test.rb" } 19 | # watch(%r{^app/views/.+$}) { 'test/integration' } 20 | # watch('app/controllers/application_controller.rb') { ['test/functional', 'test/integration'] } 21 | end 22 | -------------------------------------------------------------------------------- /lib/guard/test/version.rb: -------------------------------------------------------------------------------- 1 | module Guard 2 | module TestVersion 3 | VERSION = '2.0.8' 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /spec/lib/guard/test/inspector_spec.rb: -------------------------------------------------------------------------------- 1 | require 'guard/test/inspector' 2 | 3 | RSpec.describe Guard::Test::Inspector do 4 | 5 | describe "clean" do 6 | before { subject.test_paths = ["test"] } 7 | 8 | it "should add all test files under the given dir" do 9 | expect(subject.clean(["test"])).to \ 10 | eq ["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"] 11 | end 12 | 13 | it "should remove non-test files" do 14 | expect(subject.clean(["test/succeeding_test.rb", "bob.rb"])).to eq ["test/succeeding_test.rb"] 15 | end 16 | 17 | it "should remove non-existing test files" do 18 | expect(subject.clean(["test/succeeding_test.rb", "bob_test.rb"])).to eq ["test/succeeding_test.rb"] 19 | end 20 | 21 | it "should remove non-existing test files (2)" do 22 | expect(subject.clean(["test/bar_test.rb"])).to eq [] 23 | end 24 | 25 | it "should keep test folder path" do 26 | expect(subject.clean(["test/succeeding_test.rb", "test/unit"])).to \ 27 | eq ["test/succeeding_test.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"] 28 | end 29 | 30 | it "should remove duplication" do 31 | expect(subject.clean(["test", "test"])).to \ 32 | eq ["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"] 33 | end 34 | 35 | it "should remove test folder includes in other test folder" do 36 | expect(subject.clean(["test/unit", "test"])).to \ 37 | eq ["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"] 38 | end 39 | 40 | it "should remove test files includes in test folder" do 41 | expect(subject.clean(["test/unit/failing_test.rb", "test"])).to \ 42 | eq ["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"] 43 | end 44 | 45 | it "should remove test files includes in test folder (2)" do 46 | expect(subject.clean(["test/unit/failing_test.rb", "test/unit/error/error_test.rb", "test/unit/error"])).to \ 47 | eq ["test/unit/error/error_test.rb", "test/unit/failing_test.rb"] 48 | end 49 | 50 | context "when test_paths is not default" do 51 | before { subject.test_paths = ["test/unit/error"] } 52 | 53 | it "should clean paths not specified" do 54 | expect(subject.clean(['test/succeeding_test.rb', 'test/unit/error/error_test.rb'])).to \ 55 | eq ['test/unit/error/error_test.rb'] 56 | end 57 | end 58 | 59 | end 60 | 61 | end 62 | -------------------------------------------------------------------------------- /spec/lib/guard/test/notifier_spec.rb: -------------------------------------------------------------------------------- 1 | require 'guard/test/notifier' 2 | 3 | RSpec.describe Guard::Test::Notifier do 4 | 5 | describe "#notify(result, duration)" do 6 | context "no failure, no error" do 7 | it "displays a 'success' image" do 8 | result = create_mock_result 9 | expect(Guard::Compat::UI).to receive(:notify).with(anything, title: "Test::Unit results", image: :success) 10 | described_class.notify(result, 0) 11 | end 12 | end 13 | 14 | context "1 failure" do 15 | it "displays a 'failed' image" do 16 | result = create_mock_result(failure_count: 1) 17 | expect(Guard::Compat::UI).to receive(:notify).with(anything, title: "Test::Unit results", image: :failed) 18 | described_class.notify(result, 0) 19 | end 20 | end 21 | 22 | context "1 error" do 23 | it "displays a 'failed' image" do 24 | result = create_mock_result(error_count: 1) 25 | expect(Guard::Compat::UI).to receive(:notify).with(anything, title: "Test::Unit results", image: :failed) 26 | described_class.notify(result, 0) 27 | end 28 | end 29 | end 30 | 31 | end 32 | 33 | def create_mock_result(options={}) 34 | default = {run_count: 1, assertion_count: 1, failure_count: 0, error_count: 0} 35 | options = default.merge(options) 36 | # passed? if no failures or errors 37 | options[:passed?] = (0 == options[:failure_count] && 0 == options[:error_count]) 38 | double('result', options) 39 | end 40 | 41 | -------------------------------------------------------------------------------- /spec/lib/guard/test/runner_spec.rb: -------------------------------------------------------------------------------- 1 | require 'guard/test/runner' 2 | 3 | RSpec.describe Guard::Test::Runner do 4 | before do 5 | allow(Guard::Compat::UI).to receive(:info) 6 | end 7 | 8 | describe "#initialize" do 9 | describe "sets the @runner instance variable from options" do 10 | it "sets default options" do 11 | runner = described_class.new 12 | expect(runner.instance_variable_get(:@options)[:bundler]).to be_truthy 13 | expect(runner.instance_variable_get(:@options)[:rubygems]).to be_falsey 14 | expect(runner.instance_variable_get(:@options)[:rvm]).to be_empty 15 | expect(runner.instance_variable_get(:@options)[:drb]).to be_falsey 16 | expect(runner.instance_variable_get(:@options)[:zeus]).to be_falsey 17 | expect(runner.instance_variable_get(:@options)[:spring]).to be_falsey 18 | expect(runner.instance_variable_get(:@options)[:cli]).to eq "" 19 | end 20 | 21 | describe ":bundler option" do 22 | context "with the :drb option set to true" do 23 | it "uses drb but not bundler" do 24 | runner = described_class.new(drb: true, bundler: true) 25 | expect(runner).to be_drb 26 | expect(runner).not_to be_bundler 27 | end 28 | end 29 | 30 | context "with the :drb option set to false" do 31 | it "uses bundler but not drb" do 32 | runner = described_class.new(drb: false, bundler: true) 33 | expect(runner).not_to be_drb 34 | expect(runner).to be_bundler 35 | end 36 | end 37 | 38 | context "with the :zeus option set to true" do 39 | it "uses zeus but not bundler" do 40 | runner = described_class.new(zeus: true, bundler: true) 41 | expect(runner).to be_zeus 42 | expect(runner).not_to be_bundler 43 | end 44 | end 45 | 46 | context "with the :zeus option set to false" do 47 | it "uses bundler but not zeus" do 48 | runner = described_class.new(zeus: false, bundler: true) 49 | expect(runner).not_to be_zeus 50 | expect(runner).to be_bundler 51 | end 52 | end 53 | 54 | context "with the :spring option set to true" do 55 | it "uses spring but not bundler" do 56 | runner = described_class.new(spring: true, bundler: true) 57 | expect(runner).to be_spring 58 | expect(runner).not_to be_bundler 59 | end 60 | end 61 | 62 | context "with the :spring option set to false" do 63 | it "uses bundler but not spring" do 64 | runner = described_class.new(spring: false, bundler: true) 65 | expect(runner).not_to be_spring 66 | expect(runner).to be_bundler 67 | end 68 | end 69 | end 70 | 71 | describe ":rubygems option" do 72 | context "with the :bundler option set to true" do 73 | it "uses bundler but not rubygems" do 74 | runner = described_class.new(bundler: true, rubygems: true) 75 | expect(runner).to be_bundler 76 | expect(runner).not_to be_rubygems 77 | end 78 | end 79 | 80 | context "with the :bundler option set to false" do 81 | it "uses rubygems but not bundler" do 82 | runner = described_class.new(bundler: false, rubygems: true) 83 | expect(runner).not_to be_bundler 84 | expect(runner).to be_rubygems 85 | end 86 | end 87 | end 88 | 89 | describe ":rvm option" do 90 | it "sets the option in the instance @options hash" do 91 | runner = described_class.new(rvm: '1.9.2') 92 | expect(runner.instance_variable_get(:@options)[:rvm]).to eq '1.9.2' 93 | end 94 | end 95 | 96 | describe ":drb option" do 97 | it "uses drb" do 98 | runner = described_class.new(drb: true) 99 | expect(runner).to be_drb 100 | end 101 | end 102 | 103 | describe ":zeus option" do 104 | it "uses zeus" do 105 | runner = described_class.new(zeus: true) 106 | expect(runner).to be_zeus 107 | end 108 | end 109 | 110 | describe ":spring option" do 111 | it "uses spring" do 112 | runner = described_class.new(spring: true) 113 | expect(runner).to be_spring 114 | end 115 | end 116 | 117 | describe ":cli option" do 118 | it "sets the option in the instance @options hash" do 119 | runner = described_class.new(cli: '--show-detail-immediately') 120 | expect(runner.instance_variable_get(:@options)[:cli]).to eq '--show-detail-immediately' 121 | end 122 | end 123 | end 124 | end 125 | 126 | describe "#run" do 127 | let(:guard_test_runner_require) { "-r #{@lib_path.join('guard/test/guard_test_runner')} " } 128 | 129 | context "in empty folder" do 130 | before(:each) do 131 | allow(Dir).to receive(:pwd).and_return("empty") 132 | end 133 | 134 | context "when no :bundler option was given on initialize" do 135 | subject do 136 | runner = described_class.new 137 | runner 138 | end 139 | 140 | it "runs without bundler" do 141 | expect(subject).to receive(:system).with( 142 | "ruby -I\"lib:test\" #{guard_test_runner_require}" \ 143 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 144 | "-- --use-color --runner=guard_test" 145 | ) 146 | 147 | subject.run(["test/succeeding_test.rb"]) 148 | end 149 | end 150 | 151 | context "when the :bundler option set to true on initialize" do 152 | subject do 153 | runner = described_class.new(bundler: true) 154 | runner 155 | end 156 | 157 | it "runs with bundler" do 158 | expect(subject).to receive(:system).with( 159 | "bundle exec " \ 160 | "ruby -I\"lib:test\" -r bundler/setup #{guard_test_runner_require}" \ 161 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 162 | "-- --use-color --runner=guard_test" 163 | ) 164 | 165 | subject.run(["test/succeeding_test.rb"]) 166 | end 167 | end 168 | end 169 | 170 | context "in a folder containing a Gemfile" do 171 | context "when no :bundler option was given on initialize" do 172 | subject do 173 | runner = described_class.new 174 | runner 175 | end 176 | 177 | it "runs with bundler" do 178 | expect(subject).to receive(:system).with( 179 | "bundle exec " \ 180 | "ruby -I\"lib:test\" -r bundler/setup #{guard_test_runner_require}" \ 181 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 182 | "-- --use-color --runner=guard_test" 183 | ) 184 | 185 | subject.run(["test/succeeding_test.rb"]) 186 | end 187 | end 188 | 189 | context "when the :bundler option set to false on initialize" do 190 | subject do 191 | runner = described_class.new(bundler: false) 192 | runner 193 | end 194 | 195 | it "runs without bundler" do 196 | expect(subject).to receive(:system).with( 197 | "ruby -I\"lib:test\" #{guard_test_runner_require}" \ 198 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 199 | "-- --use-color --runner=guard_test" 200 | ) 201 | 202 | subject.run(["test/succeeding_test.rb"]) 203 | end 204 | end 205 | 206 | context "when the :rubygems option set to true (and :bundler to false) on initialize" do 207 | subject do 208 | runner = described_class.new(bundler: false, rubygems: true) 209 | runner 210 | end 211 | 212 | it "runs without bundler and require rubygems" do 213 | expect(subject).to receive(:system).with( 214 | "ruby -I\"lib:test\" -r rubygems #{guard_test_runner_require}" \ 215 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 216 | "-- --use-color --runner=guard_test" 217 | ) 218 | 219 | subject.run(["test/succeeding_test.rb"]) 220 | end 221 | end 222 | 223 | context "when no :runner option was given on initialize" do 224 | subject do 225 | runner = described_class.new 226 | runner 227 | end 228 | 229 | it "displays message with the tests that will be fired" do 230 | expect(Guard::Compat::UI).to receive(:info).with( 231 | "Running: test/unit/error/error_test.rb test/unit/failing_test.rb", reset: true 232 | ) 233 | 234 | dev_null { subject.run(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]) } 235 | end 236 | 237 | it "runs with the --runner options set to 'guard' and require default_guard_test_runner" do 238 | expect(subject).to receive(:system).with( 239 | "bundle exec " \ 240 | "ruby -I\"lib:test\" -r bundler/setup #{guard_test_runner_require}" \ 241 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 242 | "-- --use-color --runner=guard_test" 243 | ) 244 | 245 | subject.run(["test/succeeding_test.rb"]) 246 | end 247 | end 248 | 249 | context "when the :rvm option is given" do 250 | subject do 251 | runner = described_class.new(rvm: ['1.8.7', '1.9.2']) 252 | runner 253 | end 254 | 255 | it "runs with rvm exec" do 256 | expect(subject).to receive(:system).with( 257 | "rvm 1.8.7,1.9.2 exec " \ 258 | "bundle exec " \ 259 | "ruby -I\"lib:test\" -r bundler/setup #{guard_test_runner_require}" \ 260 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 261 | "-- --use-color --runner=guard_test" 262 | ) 263 | 264 | subject.run(["test/succeeding_test.rb"]) 265 | end 266 | end 267 | 268 | context "when the :include option is given" do 269 | subject do 270 | runner = described_class.new(include: %w[foo bar]) 271 | runner 272 | end 273 | 274 | it "adds the appropriate -I options" do 275 | expect(subject).to receive(:system).with( 276 | "bundle exec " \ 277 | "ruby -I\"foo\" -I\"bar\" -r bundler/setup #{guard_test_runner_require}" \ 278 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 279 | "-- --use-color --runner=guard_test" 280 | ) 281 | 282 | subject.run(["test/succeeding_test.rb"]) 283 | end 284 | 285 | context "when the :zeus option is given" do 286 | subject do 287 | runner = described_class.new(zeus: true) 288 | runner 289 | end 290 | 291 | it "does not add a -I option" do 292 | expect(subject).to_not receive(:system).with(/\-I\"foo\" \-I\"bar\"/) 293 | 294 | subject.run(["test/succeeding_test.rb"]) 295 | end 296 | end 297 | 298 | context "when the :spring option is given" do 299 | subject do 300 | runner = described_class.new(spring: true) 301 | runner 302 | end 303 | 304 | it "does not add a -I option" do 305 | expect(subject).to_not receive(:system).with(/\-I\"foo\" \-I\"bar\"/) 306 | 307 | subject.run(["test/succeeding_test.rb"]) 308 | end 309 | end 310 | 311 | end 312 | 313 | context "when the :cli option is given" do 314 | subject do 315 | runner = described_class.new(cli: '--pretty') 316 | runner 317 | end 318 | 319 | it "adds the cli option at the end of the command" do 320 | expect(subject).to receive(:system).with( 321 | "bundle exec " \ 322 | "ruby -I\"lib:test\" -r bundler/setup #{guard_test_runner_require}" \ 323 | "-e \"%w[test/succeeding_test.rb].each { |p| load p }\" " \ 324 | "-- --use-color --runner=guard_test --pretty" 325 | ) 326 | 327 | subject.run(["test/succeeding_test.rb"]) 328 | end 329 | end 330 | 331 | context "when the :message option is given" do 332 | it "displays it" do 333 | expect(Guard::Compat::UI).to receive(:info).with("That test is failing!!!", reset: true) 334 | runner = described_class.new 335 | 336 | dev_null { runner.run(["test/unit/failing_test.rb"], message: "That test is failing!!!") } 337 | end 338 | end 339 | 340 | it "loads and executes all the tests files" do 341 | runner = described_class.new 342 | expect(runner).to receive(:system).with( 343 | "bundle exec " \ 344 | "ruby -I\"lib:test\" -r bundler/setup #{guard_test_runner_require}" \ 345 | "-e \"%w[test/error/error_test.rb test/unit/failing_test.rb].each { |p| load p }\" " \ 346 | "-- --use-color --runner=guard_test" 347 | ) 348 | 349 | runner.run(["test/error/error_test.rb", "test/unit/failing_test.rb"]) 350 | end 351 | 352 | end 353 | 354 | end # #run 355 | 356 | end 357 | -------------------------------------------------------------------------------- /spec/lib/guard/test_spec.rb: -------------------------------------------------------------------------------- 1 | require 'guard/test' 2 | 3 | RSpec.describe Guard::Test do 4 | subject { described_class.new } 5 | let(:runner) { subject.instance_variable_get(:@runner) } 6 | 7 | before do 8 | allow(Guard::Compat::UI).to receive(:info) 9 | end 10 | 11 | describe "#initialize" do 12 | it "instantiates a new Runner" do 13 | expect(Guard::Test::Runner).to receive(:new) 14 | described_class.new 15 | end 16 | 17 | context "with options given" do 18 | it "passes fiven options to Guard::Test::Runner#new" do 19 | expect(Guard::Test::Runner).to receive(:new).with(rvm: ['1.8.7', '1.9.2'], bundler: false).and_return(double('runner', bundler?: true)) 20 | 21 | described_class.new(rvm: ['1.8.7', '1.9.2'], bundler: false) 22 | end 23 | end 24 | end 25 | 26 | describe "#start" do 27 | context ":all_on_start option not specified" do 28 | it "displays a start message" do 29 | expect(Guard::Compat::UI).to receive(:info).with("Guard::Test #{Guard::TestVersion::VERSION} is running, with Test::Unit #{::Test::Unit::VERSION}!", reset: true) 30 | expect(subject).to receive(:run_all) 31 | 32 | subject.start 33 | end 34 | 35 | it "calls #run_all by default" do 36 | expect(subject).to receive(:run_all) 37 | 38 | subject.start 39 | end 40 | end 41 | 42 | context ":all_on_start option is false" do 43 | subject { described_class.new(all_on_start: false) } 44 | 45 | it "doesn't call #run_all" do 46 | expect(subject).to_not receive(:run_all) 47 | 48 | subject.start 49 | end 50 | end 51 | 52 | end 53 | 54 | describe "#run_all" do 55 | it "runs all tests specified by the default :test_paths with a message" do 56 | expect(runner).to receive(:run).with(["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"],message: "Running all tests" 57 | ) 58 | subject.run_all 59 | end 60 | 61 | context "when :test_paths option specified" do 62 | subject { described_class.new(test_paths: ["test/unit/error"]) } 63 | 64 | it "runs all tests in specific directory" do 65 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb"], anything) 66 | subject.run_all 67 | end 68 | end 69 | 70 | it "cleans failed memory if passed" do 71 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(false) 72 | subject.run_on_modifications(["test/unit"]) 73 | 74 | expect(runner).to receive(:run).with(["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"], message: "Running all tests").and_return(true) 75 | subject.run_all 76 | 77 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(true) 78 | subject.run_on_modifications(["test/unit"]) 79 | end 80 | 81 | it "init test_paths for Inspector" do 82 | expect(runner).to receive(:run) 83 | expect(Guard::Test::Inspector).to receive(:test_paths=).with(["test"]) 84 | subject.run_all 85 | end 86 | end 87 | 88 | describe "#reload" do 89 | it "should clear failed_path" do 90 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(false) 91 | subject.run_on_modifications(["test/unit"]) 92 | 93 | subject.reload 94 | 95 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(true) 96 | expect(runner).to receive(:run).with(["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"], message: "Running all tests").and_return(true) 97 | subject.run_on_modifications(["test/unit"]) 98 | end 99 | end 100 | 101 | describe "#run_on_modifications" do 102 | it "runs test after run_all" do 103 | expect(runner).to receive(:run) 104 | subject.run_all 105 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb"]) 106 | subject.run_on_modifications(["test/unit/error/error_test.rb"]) 107 | end 108 | 109 | it "init test_paths for Inspector" do 110 | expect(Guard::Test::Inspector).to receive(:test_paths=).with(["test"]) 111 | subject.run_on_modifications([]) 112 | end 113 | 114 | context ":all_after_pass option not specified" do 115 | it "runs test with under given paths, recursively" do 116 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]) 117 | subject.run_on_modifications(["test/unit"]) 118 | end 119 | 120 | it "calls #run_all by default if the changed specs pass after failing" do 121 | expect(runner).to receive(:run).with(["test/succeeding_test.rb"]).and_return(false, true) 122 | expect(runner).to receive(:run).with(["test/succeeding_test.rb", "test/succeeding_tests.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"], message: "Running all tests") 123 | 124 | subject.run_on_modifications(["test/succeeding_test.rb"]) 125 | subject.run_on_modifications(["test/succeeding_test.rb"]) 126 | end 127 | 128 | it "doesn't call #run_all if the changed specs pass without failing" do 129 | expect(runner).to receive(:run).with(["test/succeeding_test.rb"]).and_return(true) 130 | expect(runner).to_not receive(:run).with(["test/succeeding_test.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"], message: "Running all tests") 131 | subject.run_on_modifications(["test/succeeding_test.rb"]) 132 | end 133 | end 134 | 135 | context ":all_after_pass option is false" do 136 | subject { described_class.new(all_after_pass: false) } 137 | 138 | it "doesn't call #run_all if the changed specs pass after failing but the :all_after_pass option is false" do 139 | expect(runner).to receive(:run).with(["test/succeeding_test.rb"]).and_return(false, true) 140 | expect(runner).to_not receive(:run).with(["test/succeeding_test.rb", "test/test_old.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"], message: "Running all tests") 141 | 142 | subject.run_on_modifications(["test/succeeding_test.rb"]) 143 | subject.run_on_modifications(["test/succeeding_test.rb"]) 144 | end 145 | end 146 | 147 | context ":keep_failed option not specified" do 148 | subject { described_class.new(all_after_pass: false) } 149 | 150 | it "keeps failed specs and rerun later by default" do 151 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(false) 152 | subject.run_on_modifications(["test/unit"]) 153 | 154 | expect(runner).to receive(:run).with(["test/succeeding_test.rb", "test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(true) 155 | subject.run_on_modifications(["test/succeeding_test.rb"]) 156 | 157 | expect(runner).to receive(:run).with(["test/succeeding_test.rb"]).and_return(true) 158 | subject.run_on_modifications(["test/succeeding_test.rb"]) 159 | end 160 | end 161 | 162 | context ":keep_failed option is false" do 163 | subject { described_class.new(all_after_pass: false, keep_failed: false) } 164 | 165 | it "doesn't keep failed specs" do 166 | expect(runner).to receive(:run).with(["test/unit/error/error_test.rb", "test/unit/failing_test.rb"]).and_return(false) 167 | subject.run_on_modifications(["test/unit"]) 168 | 169 | expect(runner).to receive(:run).with(["test/succeeding_test.rb"]).and_return(true) 170 | subject.run_on_modifications(["test/succeeding_test.rb"]) 171 | 172 | expect(runner).to receive(:run).with(["test/succeeding_test.rb"]).and_return(true) 173 | subject.run_on_modifications(["test/succeeding_test.rb"]) 174 | end 175 | end 176 | 177 | end 178 | 179 | end 180 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'guard/compat/test/helper' 2 | 3 | require 'codeclimate-test-reporter' 4 | CodeClimate::TestReporter.start 5 | 6 | RSpec.configure do |config| 7 | config.expect_with :rspec do |expectations| 8 | expectations.include_chain_clauses_in_custom_matcher_descriptions = true 9 | end 10 | 11 | config.mock_with :rspec do |mocks| 12 | mocks.verify_partial_doubles = true 13 | end 14 | 15 | config.filter_run focus: ENV['CI'] != 'true' 16 | config.run_all_when_everything_filtered = true 17 | 18 | config.disable_monkey_patching! 19 | 20 | # config.warnings = true 21 | 22 | config.default_formatter = 'doc' if config.files_to_run.one? 23 | 24 | # config.profile_examples = 10 25 | 26 | config.order = :random 27 | 28 | Kernel.srand config.seed 29 | 30 | config.before(:all) do 31 | @lib_path = Pathname.new(File.expand_path('../../lib/', __FILE__)) 32 | end 33 | end 34 | 35 | # Thanks to Jonas Pfenniger for this! 36 | # http://gist.github.com/487157 37 | def dev_null(&block) 38 | orig_stdout = $stdout.dup # does a dup2() internally 39 | $stdout.reopen('/dev/null', 'w') 40 | yield 41 | ensure 42 | $stdout.reopen(orig_stdout) 43 | end 44 | -------------------------------------------------------------------------------- /test/succeeding_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SucceedingTest < Test::Unit::TestCase 4 | def test_succeeding1 5 | assert_equal(true, true) 6 | end 7 | def test_succeeding2 8 | assert_equal(true, true) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/succeeding_tests.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SucceedingTests < Test::Unit::TestCase 4 | def test_succeeding1 5 | assert_equal(true, true) 6 | end 7 | def test_succeeding2 8 | assert_equal(true, true) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'test/unit/autorunner' 2 | -------------------------------------------------------------------------------- /test/test_old.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class TestOld < Test::Unit::TestCase 4 | def test_old1 5 | assert_equal(true, true) 6 | end 7 | def test_old2 8 | assert_equal(true, true) 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /test/unit/error/error_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class ErrorTest < Test::Unit::TestCase 4 | def test_error 5 | raise "Error!" 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /test/unit/failing_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FailingTest < Test::Unit::TestCase 4 | def test_failing1 5 | assert_equal(true, false) 6 | end 7 | def test_failing2 8 | assert_equal(true, false) 9 | end 10 | end 11 | --------------------------------------------------------------------------------