summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKyrylo Silin <silin@kyrylo.org>2019-05-26 14:23:06 +0300
committerGitHub <noreply@github.com>2019-05-26 14:23:06 +0300
commit28cf3e9fa83ac5e602a18917fdb8b1539c06ca96 (patch)
treebccc95d8a39adae14513eb709c915148eb7b485f
parent7ca5facc1cf6b9021928ff4fcb7f6874cce904c5 (diff)
parentef72f221b101d464807f2df28828b275ba10688d (diff)
downloadpry-28cf3e9fa83ac5e602a18917fdb8b1539c06ca96.tar.gz
Merge pull request #2043 from pry/output-refactoring
Refactor Pry::Output and add tests
-rw-r--r--lib/pry/output.rb22
-rw-r--r--spec/output_spec.rb197
2 files changed, 207 insertions, 12 deletions
diff --git a/lib/pry/output.rb b/lib/pry/output.rb
index 6ecd8752..91373843 100644
--- a/lib/pry/output.rb
+++ b/lib/pry/output.rb
@@ -5,8 +5,8 @@ class Pry
attr_reader :pry_instance
def initialize(pry_instance)
- @pry_instance = pry_instance
- @boxed_io = pry_instance.config.output
+ @output = pry_instance.config.output
+ @color = pry_instance.config.color
end
def puts(*objs)
@@ -24,7 +24,7 @@ class Pry
def print(*objs)
objs.each do |obj|
- @boxed_io.print decolorize_maybe(obj.to_s)
+ @output.print decolorize_maybe(obj.to_s)
end
nil
end
@@ -32,27 +32,25 @@ class Pry
alias write print
def tty?
- @boxed_io.respond_to?(:tty?) && @boxed_io.tty?
+ @output.respond_to?(:tty?) && @output.tty?
end
def method_missing(method_name, *args, &block)
- if @boxed_io.respond_to?(method_name)
- @boxed_io.__send__(method_name, *args, &block)
+ if @output.respond_to?(method_name)
+ @output.__send__(method_name, *args, &block)
else
super
end
end
def respond_to_missing?(method_name, include_private = false)
- @boxed_io.respond_to?(method_name, include_private)
+ @output.respond_to?(method_name, include_private)
end
def decolorize_maybe(str)
- if pry_instance.config.color
- str
- else
- Pry::Helpers::Text.strip_color str
- end
+ return str if @color
+
+ Pry::Helpers::Text.strip_color(str)
end
end
end
diff --git a/spec/output_spec.rb b/spec/output_spec.rb
new file mode 100644
index 00000000..40ccddc9
--- /dev/null
+++ b/spec/output_spec.rb
@@ -0,0 +1,197 @@
+# frozen_string_literal: true
+
+RSpec.describe Pry::Output do
+ let(:output) { StringIO.new }
+ let(:pry_instance) { Pry.new(output: output) }
+
+ subject { described_class.new(pry_instance) }
+
+ describe "#puts" do
+ it "returns nil" do
+ expect(subject.puts).to be_nil
+ end
+
+ context "when given an empty array" do
+ it "prints a newline" do
+ subject.puts([])
+ expect(output.string).to eq("\n")
+ end
+ end
+
+ context "when given multiple empty arrays" do
+ it "prints multiple newline" do
+ subject.puts([], [], [])
+ expect(output.string).to eq("\n\n\n")
+ end
+ end
+
+ context "when given convertible to array objects" do
+ let(:obj) do
+ Object.new.tap { |o| o.define_singleton_method(:to_ary) { [1] } }
+ end
+
+ let(:other_obj) do
+ Object.new.tap { |o| o.define_singleton_method(:to_ary) { [2] } }
+ end
+
+ it "prints the converted objects" do
+ subject.puts([obj, other_obj])
+ expect(output.string).to eq("1\n2\n")
+ end
+ end
+
+ context "when given non-convertible to array objects" do
+ let(:obj) { Object.new }
+ let(:other_obj) { Object.new }
+
+ it "prints the non-converted objects in its string form" do
+ subject.puts([obj, other_obj])
+ expect(output.string).to match(/\A#<Object:.+>\n#<Object:.+>\n\z/)
+ end
+
+ context "and when the object's #to_s has a newline" do
+ let(:obj) do
+ Object.new.tap { |o| o.define_singleton_method(:to_s) { "abc\n" } }
+ end
+
+ it "doesn't print a double newline" do
+ subject.puts(obj)
+ expect(output.string).to eq("abc\n")
+ end
+ end
+ end
+
+ context "when the given pry instance has 'color' enabled" do
+ let(:pry_instance) { Pry.new(output: output, color: true) }
+
+ it "doesn't decolorize output" do
+ subject.puts("\e[30mhi\e[0m")
+ expect(output.string).to eq("\e[30mhi\e[0m\n")
+ end
+ end
+
+ context "when the given pry instance has 'color' disabled" do
+ let(:pry_instance) { Pry.new(output: output, color: false) }
+
+ it "decolorizes output" do
+ subject.puts("\e[30mhi\e[0m")
+ expect(output.string).to eq("hi\n")
+ end
+ end
+ end
+
+ describe "#print" do
+ it "returns nil" do
+ expect(subject.print).to be_nil
+ end
+
+ context "when the given pry instance has 'color' enabled" do
+ let(:pry_instance) { Pry.new(output: output, color: true) }
+
+ it "doesn't decolorize output" do
+ subject.print("\e[30mhi\e[0m")
+ expect(output.string).to eq("\e[30mhi\e[0m")
+ end
+ end
+
+ context "when the given pry instance has 'color' disabled" do
+ let(:pry_instance) { Pry.new(output: output, color: false) }
+
+ it "decolorizes output" do
+ subject.print("\e[30mhi\e[0m")
+ expect(output.string).to eq('hi')
+ end
+ end
+ end
+
+ describe "#<<" do
+ specify { expect(subject.method(:<<)).to eq(subject.method(:print)) }
+ end
+
+ describe "#write" do
+ specify { expect(subject.method(:write)).to eq(subject.method(:print)) }
+ end
+
+ describe "#tty?" do
+ context "when the output responds to #tty? and is a TTY" do
+ before { expect(output).to receive(:tty?).and_return(true) }
+
+ it "returns true" do
+ expect(subject).to be_tty
+ end
+ end
+
+ context "when the output responds to #tty? and is not a TTY" do
+ before do
+ expect(output).to receive(:respond_to?).with(:tty?).and_return(true)
+ expect(output).to receive(:tty?).and_return(false)
+ end
+
+ it "returns false" do
+ expect(subject).not_to be_tty
+ end
+ end
+
+ context "when the output doesn't respond to #tty?" do
+ before do
+ expect(output).to receive(:respond_to?).with(:tty?).and_return(false)
+ end
+
+ it "returns false" do
+ expect(subject).not_to be_tty
+ end
+ end
+ end
+
+ describe "#method_missing" do
+ context "when the output responds to the given method name" do
+ it "forwards the method to the output" do
+ expect(output).to receive(:abcd)
+ subject.abcd
+ end
+ end
+
+ context "when the output doesn't respond to the given method name" do
+ it "raises NoMethodError" do
+ expect { subject.abcd }.to raise_error(NoMethodError)
+ end
+ end
+ end
+
+ describe "#respond_to_missing?" do
+ context "when the output responds to the given method name" do
+ before { output.define_singleton_method(:test_method) {} }
+
+ it "finds the method that is not defined on self" do
+ expect(subject).to respond_to(:test_method)
+ expect(subject.method(:test_method)).to be_a(Method)
+ end
+ end
+
+ context "when the output doesn't respond to the given method name" do
+ it "doesn't find the method" do
+ expect(subject).not_to respond_to(:test_method)
+ expect { subject.method(:test_method) }.to raise_error(NameError)
+ end
+ end
+ end
+
+ describe "#decolorize_maybe" do
+ context "when the given pry instance has 'color' enabled" do
+ let(:pry_instance) { Pry.new(output: output, color: true) }
+
+ it "returns the given string without modifications" do
+ str = "\e[30mhi\e[0m"
+ expect(subject.decolorize_maybe(str)).to eql(str)
+ end
+ end
+
+ context "when the given pry instance has 'color' disabled" do
+ let(:pry_instance) { Pry.new(output: output, color: false) }
+
+ it "returns decolorized string" do
+ expect(subject.decolorize_maybe("\e[30mhi\e[0m")).to eq('hi')
+ end
+ end
+ end
+end