Skip to content

Commit

Permalink
Merge pull request #57 from grosser/grosser/helpers
Browse files Browse the repository at this point in the history
new pending / with_env / capture_stdX helpers
  • Loading branch information
grosser authored Oct 9, 2023
2 parents 8e0d08c + 40370e3 commit 88866ea
Show file tree
Hide file tree
Showing 7 changed files with 182 additions and 36 deletions.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ Features
- `pending { assert false }` is skip when it fails, but fails when it passes
- implicit subject via `require 'maxitest/implicit_subject'`
- `xit` to skip test (also does not call setup or teardown)
- `with_env` to change environment variables during test run
- `capture_stdout` and `capture_stderr` to capture stdout or stderr but not both (like `capture_io` does)
- `require 'maxitest/timeout'` to make hanging tests fail after `Maxitest.timeout` seconds
- `require 'maxitest/threads'` fail tests that leave extra threads running
- `require 'maxitest/global_must'` (before autorun) disable deprecation on global `must_*` or [global_expectations](https://github.com/jeremyevans/minitest-global_expectations) gem
Expand All @@ -42,6 +44,11 @@ require "maxitest/autorun"
... normal tests ...
```

### pending

- `pending "need to fix" do` to show why something is pending
- `pending "need to fix", if: ENV["CI"] do` to only skip on CI (if something is supposed to work locally)

Development
===========
- everything vendored into 1 gem to avoid dependency madness
Expand Down
6 changes: 6 additions & 0 deletions lib/maxitest/autorun.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
require "maxitest/let_all"
require "maxitest/hook_all"
require "maxitest/pending"
require "maxitest/helpers"
require "maxitest/xit"
require "maxitest/static_class_order"
require "maxitest/shorted_backtrace"
Expand All @@ -20,3 +21,8 @@ module Maxitest
class << Minitest::Test
alias_method :order_dependent!, :i_suck_and_my_tests_are_order_dependent!
end

# do not show maxitest as causing errors, but the last line in the users code
old = MiniTest::BacktraceFilter::MT_RE
MiniTest::BacktraceFilter.send(:remove_const, :MT_RE)
MiniTest::BacktraceFilter::MT_RE = Regexp.union(old, %r%lib/maxitest%)
54 changes: 54 additions & 0 deletions lib/maxitest/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
module Maxitest
module Helpers
module InstanceMethods
def with_env(env)
_synchronize do
old = ENV.to_h
env.each { |k, v| ENV[k.to_s] = v }
yield
ensure
ENV.replace old
end
end

# stripped down version of capture_io
def capture_stdout
_synchronize do
begin
captured_stdout = StringIO.new
orig_stdout = $stdout
$stdout = captured_stdout
yield
return captured_stdout.string
ensure
$stdout = orig_stdout
end
end
end

# stripped down version of capture_io
def capture_stderr
_synchronize do
begin
captured_stderr = StringIO.new
orig_stderr = $stderr
$stderr = captured_stderr
yield
return captured_stderr.string
ensure
$stderr = orig_stderr
end
end
end
end

module ClassMethods
def with_env(env)
around { |t| with_env(env, &t) }
end
end
end
end

Minitest::Test.send(:include, Maxitest::Helpers::InstanceMethods)
Minitest::Test.send(:extend, Maxitest::Helpers::ClassMethods)
20 changes: 10 additions & 10 deletions lib/maxitest/pending.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
module Maxitest
module Pending
def pending(reason=nil)
if block_given?
begin
yield
rescue StandardError, Minitest::Assertion
skip reason
else
raise "Fixed"
end
def pending(reason=nil, **kwargs)
raise ArgumentError, "Need a block to execute" unless block_given?
raise ArgumentError, "Only :if option is supported" if (kwargs.keys | [:if] != [:if])
return yield if kwargs.fetch(:if, true) == false # allow user to for example mark test only pending on CI with `if: ENV["CI"]`

begin
yield # execute test
rescue StandardError, Minitest::Assertion
skip reason # test failed as expected
else
raise ArgumentError, "Need a block to execute"
flunk "Test is fixed, remove `pending`"
end
end
end
Expand Down
52 changes: 52 additions & 0 deletions spec/cases/helpers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
require "./spec/cases/helper"

describe "helpers" do
describe "#with_env" do
it "changes env" do
with_env A: "b" do
_(ENV["A"]).must_equal "b"
end
end

it "restores env" do
ENV["A"] = "c"
with_env A: "b" do
ENV["B"] = "a"
_(ENV["A"]).must_equal "b"
end
_(ENV["A"]).must_equal "c"
_(ENV["B"]).must_be_nil
end
end

describe ".with_env" do
with_env A: "a"
it "sets env" do
_(ENV["A"]).must_equal "a"
end
end

describe "#capture_stdout" do
it "keeps stdout" do
_(capture_stdout { puts "X" }).must_equal "X\n"
end

it "lets stderr through" do
out, err = capture_io { capture_stdout { warn "X" } }
_(out).must_equal ""
_(err).must_equal "X\n"
end
end

describe "#capture_stderr" do
it "keeps stderr" do
_(capture_stderr { warn "X" }).must_equal "X\n"
end

it "lets stdout through" do
out, err = capture_io { capture_stderr { puts "X" } }
_(out).must_equal "X\n"
_(err).must_equal ""
end
end
end
60 changes: 46 additions & 14 deletions spec/cases/pending.rb
Original file line number Diff line number Diff line change
@@ -1,35 +1,67 @@
require "./spec/cases/helper"

describe 2 do
it "is even" do
2.even?.must_equal true
it "runs regular tests" do
_(2.even?).must_equal true
end

it "is not odd" do
pending "fail" do
2.must_equal 2
it "fails when pending is fixed" do
e = assert_raises Minitest::Assertion do
pending "fail" do
_(2).must_equal 2
end
end
_(e.message).must_include "fixed"
end

it "pends" do
pending "Skipping with a reason" do
2.must_equal 3
it "skips when pending still needed" do
e = assert_raises Minitest::Skip do
pending "Skipping with reason" do
_(2).must_equal 3, "This should not fail"
end
end
_(e.message).must_equal "Skipping with reason"
end

it "pends exceptions" do
pending "Skipping with exception" do
raise "Oh noes"
it "skips exceptions" do
e = assert_raises Minitest::Skip do
pending "Skipping with exception" do
raise "Oh noes"
end
end
_(e.message).must_equal "Skipping with exception"
end

it "pends without text" do
it "skips without reason" do
pending do
2.must_equal 3
_(2).must_equal 3
end
end

it "fails without block" do
pending "success"
e = assert_raises(ArgumentError) do
pending "success"
end
_(e.message).must_equal "Need a block to execute"
end

it "can disable pending" do
pending "Not skipping", if: false do
_(2).must_equal 2
end
end

it "can enable pending" do
pending "skipping conditionally", if: true do
raise "Oh noes"
end
end

it "fails when given unknown kwargs" do
assert_raises(ArgumentError) do
pending "skipping conditionally", unless: true do
raise "Oh noes"
end
end
end
end
19 changes: 7 additions & 12 deletions spec/maxitest_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,7 @@
end

it "has pending" do
result = run_cmd("ruby spec/cases/pending.rb -v", :fail => true)
result.should include "ArgumentError: Need a block to execute" # fails without block
result.should include "RuntimeError: Fixed" # shows fixed when pending failed
result.should include "Skipped, no message given" # skip without message
result.should include "Skipping with a reason" # skip with message
result.should include "6 runs, 4 assertions, 0 failures, 2 errors, 3 skips"
run_cmd("ruby spec/cases/pending.rb")
end

it "does not call xit specs" do
Expand All @@ -62,13 +57,13 @@
out.gsub!(/\n.*previous definition of Timeout.*/, "")
output_in = out.gsub!(/:in .*/, "")

output_in.should include <<-TEXT.gsub(" ", "")
TypeError: Timeout is not a module
lib/maxitest/timeout.rb:9
lib/maxitest/timeout.rb:4
TEXT

output_in.should include "TypeError: Timeout is not a module"
output_in.should include 'spec/cases/raise.rb:11'
output_in.should_not include 'lib/maxitest'
end

it "has helpers" do
run_cmd("ruby spec/cases/helpers.rb")
end

describe "before/after/around" do
Expand Down

0 comments on commit 88866ea

Please sign in to comment.