diff options
author | Kyrylo Silin <silin@kyrylo.org> | 2019-05-26 14:23:06 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-05-26 14:23:06 +0300 |
commit | 28cf3e9fa83ac5e602a18917fdb8b1539c06ca96 (patch) | |
tree | bccc95d8a39adae14513eb709c915148eb7b485f | |
parent | 7ca5facc1cf6b9021928ff4fcb7f6874cce904c5 (diff) | |
parent | ef72f221b101d464807f2df28828b275ba10688d (diff) | |
download | pry-28cf3e9fa83ac5e602a18917fdb8b1539c06ca96.tar.gz |
Merge pull request #2043 from pry/output-refactoring
Refactor Pry::Output and add tests
-rw-r--r-- | lib/pry/output.rb | 22 | ||||
-rw-r--r-- | spec/output_spec.rb | 197 |
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 |