require 'spec_helper' require 'hexdump/theme/rule' describe Hexdump::Theme::Rule do describe "#initialize" do context "when no style is given" do subject { described_class.new } it "must set #style to nil" do expect(subject.style).to be(nil) end end context "when given a style" do let(:style) { :bold } subject { described_class.new(style: style) } it "must initialize #style based on the given style" do expect(subject.style).to be_kind_of(Hexdump::Theme::ANSI) expect(subject.style.parameters).to eq(style) end end context "when given no highlights: keyword argument" do it "must initialize #highlight_strings to {}" do expect(subject.highlight_strings).to eq({}) end it "must initialize #highlight_regexps to {}" do expect(subject.highlight_regexps).to eq({}) end end context "when given the highlights: keyword argument" do let(:highlights) { {/[a-f]/ => :green, '00' => :red} } subject { described_class.new(highlights: highlights) } it "must populate #highlight_strings with the String keys" do expect(subject.highlight_strings['00']).to be_kind_of(Hexdump::Theme::ANSI) expect(subject.highlight_strings['00'].parameters).to eq(:red) end it "must populate #highlight_regexps with the Regexp keys" do expect(subject.highlight_regexps[/[a-f]/]).to be_kind_of(Hexdump::Theme::ANSI) expect(subject.highlight_regexps[/[a-f]/].parameters).to eq(:green) end end end describe "#highlights" do let(:highlights) { {/[a-f]/ => :green, '00' => :red} } subject { described_class.new(highlights: highlights) } it "must combine #highlight_strings and #highlight_regexps" do expect(subject.highlights).to eq(subject.highlight_strings.merge(subject.highlight_regexps)) end end describe "#highlight" do context "when given a String pattern" do let(:pattern) { '00' } let(:style) { :red } before { subject.highlight(pattern,style) } it "must populate #highlight_strings with the given String" do expect(subject.highlight_strings[pattern]).to be_kind_of(Hexdump::Theme::ANSI) expect(subject.highlight_strings[pattern].parameters).to eq(style) end end context "when given a Regexp pattern" do let(:pattern) { /[a-f]/ } let(:style) { :green } before { subject.highlight(pattern,style) } it "must populate #highlight_regexps with the given Regexp" do expect(subject.highlight_regexps[pattern]).to be_kind_of(Hexdump::Theme::ANSI) expect(subject.highlight_regexps[pattern].parameters).to eq(style) end end context "when not given a String or Regexp" do let(:pattern) { Object.new } let(:style) { :red } it do expect { subject.highlight(pattern,style) }.to raise_error(ArgumentError,"pattern must be a String or Regexp: #{pattern.inspect}") end end end describe "#apply" do let(:string) { "00f0" } let(:highlights) { {'00' => :faint, /[a-f]/ => :green} } let(:reset) { Hexdump::Theme::ANSI::RESET } let(:red) { Hexdump::Theme::ANSI::PARAMETERS[:red] } let(:green) { Hexdump::Theme::ANSI::PARAMETERS[:green] } context "when there are #highlight_strings rules" do let(:highlights) { {"00" => :red} } subject { described_class.new(highlights: highlights) } context "and the whole string matches a #highlight_strings rule" do let(:string) { '00' } it "must highlight the whole string" do expect(subject.apply(string)).to eq("#{red}#{string}#{reset}") end end context "but the string does not match any of the rules" do let(:string) { 'ff' } it "must return the given String" do expect(subject.apply(string)).to eq(string) end end end context "when there are #highlight_regexps rules" do let(:highlights) { {/f/ => :green} } subject { described_class.new(highlights: highlights) } context "and the whole string matches a #highlight_strings rule" do let(:string) { '00f0' } it "must highlight the matching substrings within the string" do expect(subject.apply(string)).to eq("00#{green}f#{reset}0") end context "and #style is initialized" do subject do described_class.new( style: :cyan, highlights: highlights ) end it "must re-enable the default style after resetting the highlighting" do expect(subject.apply(string)).to include("#{green}f#{reset}#{subject.style}") end context "when the beginning of the string is not highlighted" do let(:string) { "0f" } it "must prepend the string with the default style" do expect(subject.apply(string)).to eq("#{subject.style}0#{green}f#{reset}") end end context "when the end of the string is not highlighted" do let(:string) { "f0" } it "must append ANSI reset to the end of the string" do expect(subject.apply(string)).to eq("#{green}f#{reset}#{subject.style}0#{reset}") end end end end context "but the string does not match any of the rules" do let(:string) { '0000' } it "must return the given String" do expect(subject.apply(string)).to eq(string) end end end context "when #style is initialized" do let(:style) { :cyan } subject { described_class.new(style: style) } it "must wrap the given string with the style's ANSI string and reset" do expect(subject.apply(string)).to eq("#{subject.style}#{string}#{reset}") end end context "when #style is not initialized" do let(:string) { 'ff' } it "must return the given String" do expect(subject.apply(string)).to eq(string) end end end end