summaryrefslogtreecommitdiff
path: root/spec/commands
diff options
context:
space:
mode:
authorKyrylo Silin <silin@kyrylo.org>2019-05-11 14:13:13 +0300
committerKyrylo Silin <silin@kyrylo.org>2019-05-11 16:32:41 +0300
commitaa173f41146bdc97c33fd0dc4a823c9a8b6a3ea4 (patch)
tree8d505f3f5cfb62d6df490d7722203b1e8e3ca32a /spec/commands
parentd89a2584f44f04e3211269f461dc742fab54a3d9 (diff)
downloadpry-aa173f41146bdc97c33fd0dc4a823c9a8b6a3ea4.tar.gz
commands/wtf_spec: refactor unit tests
Although this is more verbose now, it looks more like proper unit tests. The tester API needs to be revamped because `tester.eval` is *not* unit testing.
Diffstat (limited to 'spec/commands')
-rw-r--r--spec/commands/wtf_spec.rb173
1 files changed, 149 insertions, 24 deletions
diff --git a/spec/commands/wtf_spec.rb b/spec/commands/wtf_spec.rb
index ace8cbf3..3af52eff 100644
--- a/spec/commands/wtf_spec.rb
+++ b/spec/commands/wtf_spec.rb
@@ -1,39 +1,164 @@
# frozen_string_literal: true
-describe "wtf?!" do
- let(:tester) do
- pry_tester do
- def last_exception=(exception)
- @pry.last_exception = exception
+RSpec.describe Pry::Command::Wtf do
+ describe "#process" do
+ let(:output) { StringIO.new }
+
+ let(:exception) do
+ error = RuntimeError.new('oops')
+ error.set_backtrace(Array.new(6) { "/bin/pry:23:in `<main>'" })
+ error
+ end
+
+ let(:pry_instance) do
+ instance = Pry.new
+ instance.last_exception = exception
+ instance
+ end
+
+ before do
+ subject.pry_instance = pry_instance
+ subject.output = output
+ subject.opts = Pry::Slop.new
+ subject.captures = ['']
+ end
+
+ context "when there wasn't an exception raised" do
+ before { subject.pry_instance = Pry.new }
+
+ it "raises Pry::CommandError" do
+ expect { subject.process }
+ .to raise_error(Pry::CommandError, 'No most-recent exception')
end
+ end
+
+ context "when the verbose flag is missing" do
+ before { expect(subject.opts).to receive(:verbose?).and_return(false) }
- def last_exception
- @pry.last_exception
+ it "prints only a part of the exception backtrace" do
+ subject.process
+ expect(subject.output.string).to eq(
+ "\e[1mException:\e[0m RuntimeError: oops\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n"
+ )
+ end
+ end
+
+ context "when the verbose flag is present" do
+ before { expect(subject.opts).to receive(:verbose?).and_return(true) }
+
+ it "prints full exception backtrace" do
+ subject.process
+ expect(subject.output.string).to eq(
+ "\e[1mException:\e[0m RuntimeError: oops\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n" \
+ "5: /bin/pry:23:in `<main>'\n"
+ )
end
end
- end
- it "unwinds nested exceptions" do
- if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('2.0.0')
- skip('Exception#cause is not supported')
+ context "when captures contains exclamations (wtf?! invocation)" do
+ before { subject.captures = ['!'] }
+
+ it "prints more of backtrace" do
+ subject.process
+ expect(subject.output.string).to eq(
+ "\e[1mException:\e[0m RuntimeError: oops\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n" \
+ "5: /bin/pry:23:in `<main>'\n" \
+ )
+ end
end
- begin
- begin
+ context "when given a nested exception" do
+ let(:nested_exception) do
begin
- raise 'inner'
- rescue RuntimeError
- raise 'outer'
+ begin
+ begin
+ raise 'inner'
+ rescue RuntimeError
+ raise 'outer'
+ end
+ end
+ rescue RuntimeError => error
+ error.set_backtrace(Array.new(6) { "/bin/pry:23:in `<main>'" })
+ error.cause.set_backtrace(Array.new(6) { "/bin/pry:23:in `<main>'" })
+ error
end
end
- rescue RuntimeError => ex
- tester.last_exception = ex
- end
- expect(tester.eval('wtf -v')).to match(/
- Exception:\sRuntimeError:\souter
- .+
- Caused\sby:\sRuntimeError:\sinner
- /xm)
+ before do
+ if Gem::Version.new(RUBY_VERSION) <= Gem::Version.new('2.0.0')
+ skip('Exception#cause is not supported')
+ end
+
+ pry_instance.last_exception = nested_exception
+ end
+
+ context "and when the verbose flag is missing" do
+ before { expect(subject.opts).to receive(:verbose?).twice.and_return(false) }
+
+ it "prints parts of both original and nested exception backtrace" do
+ subject.process
+ expect(subject.output.string).to eq(
+ "\e[1mException:\e[0m RuntimeError: outer\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n" \
+ "\e[1mCaused by:\e[0m RuntimeError: inner\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n"
+ )
+ end
+ end
+
+ context "and when the verbose flag present" do
+ before { expect(subject.opts).to receive(:verbose?).twice.and_return(true) }
+
+ it "prints both original and nested exception backtrace" do
+ subject.process
+ expect(subject.output.string).to eq(
+ "\e[1mException:\e[0m RuntimeError: outer\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n" \
+ "5: /bin/pry:23:in `<main>'\n" \
+ "\e[1mCaused by:\e[0m RuntimeError: inner\n" \
+ "--\n" \
+ "0: /bin/pry:23:in `<main>'\n" \
+ "1: /bin/pry:23:in `<main>'\n" \
+ "2: /bin/pry:23:in `<main>'\n" \
+ "3: /bin/pry:23:in `<main>'\n" \
+ "4: /bin/pry:23:in `<main>'\n" \
+ "5: /bin/pry:23:in `<main>'\n"
+ )
+ end
+ end
+ end
end
end