card/spec/card/diff_spec.rb
# -*- encoding : utf-8 -*-
RSpec.describe Card::Content::Diff do
def del text
"<del class='diffdel diff-deleted'>#{text}</del>"
end
def ins text
"<ins class='diffins diff-added'>#{text}</ins>"
end
def tag text
"<#{text}>"
end
def diff old_s, new_s, options=opts
Card::Content::Diff.complete(old_s, new_s, options)
end
def summary old_s, new_s, options=opts
Card::Content::Diff.summary(old_s, new_s, options)
end
old_p = "<p>old</p>"
new_h = "<h1>new</h1>"
def p_diff
diff "<p>old</p>", "<p>new</p>"
end
describe "traffic light" do
it "is green for addition" do
a = "a"
b = "a b"
db = described_class.new(a, b)
expect(db).to be_green
expect(db).not_to be_red
end
it "is red for deletion" do
a = "a"
b = ""
db = described_class.new(a, b)
expect(db).not_to be_green
expect(db).to be_red
end
it "is green and red for change" do
a = "a"
b = "b"
db = described_class.new(a, b)
expect(db).to be_green
expect(db).to be_red
end
it "is off for no change" do
a = "a"
b = "a"
db = described_class.new(a, b)
expect(db).not_to be_green
expect(db).not_to be_red
end
end
describe "summary" do
let(:opts) { { diff_format: :html } }
it "omits unchanged text" do
a = "<p>this was the original string</p>"
b = "<p>this is the new string</p>"
expect(summary(a, b)).to eq(
"...#{del 'was'}#{ins 'is'}...#{del 'original'}#{ins 'new'}..."
)
end
it "no ellipsis if changes fit exactly" do
a = "123"
b = "456"
expect(summary(a, b, summary: { length: 6 })).to eq(
"#{del '123'}#{ins '456'}"
)
end
it "green ellipsis if added text does not fit" do
a = "123"
b = "5678"
expect(summary(a, b, summary: { length: 6 })).to eq(
"#{del '123'}#{ins '...'}"
)
end
it "neutral ellipsis if complete change does not fit" do
a = "123 123"
b = "456 456"
expect(summary(a, b, summary: { length: 9 })).to eq(
"#{del '123'}#{ins '456'}..."
)
end
it "red ellipsis if deleted text partially fits" do
a = "123456"
b = "567"
expect(summary(a, b, summary: { length: 4 })).to eq(
(del "1...").to_s
)
end
it "green ellipsis if added text partially fits" do
a = "1234"
b = "56789"
expect(summary(a, b, summary: { length: 8 })).to eq(
"#{del '1234'}#{ins '5...'}"
)
end
it "removes html tags" do
a = "<a>A</a>"
b = "<b>B</b>"
expect(summary(a, b, diff_format: :html)).to eq(
"#{del 'A'}#{ins 'B'}"
)
end
it "with html tags in raw format" do
a = "<a>1</a>"
b = "<b>1</b>"
expect(summary(a, b, diff_format: :raw)).to eq(
"#{del(tag('a'))}#{ins(tag('b'))}...#{del(tag('/a'))}#{ins(tag('/b'))}"
)
end
end
context "html format" do
let(:opts) { { diff_format: :html } }
it "doesn't change a text without changes" do
text = "Hello World!\n How are you?"
expect(diff(text, text)).to eq(text)
end
it "preserves html" do
expect(p_diff).to eq("<p>#{del 'old'}#{ins 'new'}</p>")
end
it "ignores html changes" do
expect(diff(old_p, new_h)).to eq("<h1>#{del 'old'}#{ins 'new'}</h1>")
end
it "diff with multiple paragraphs" do
a = "<p>this was the original string</p>"
b = "<p>this is</p>\n<p> the new string</p>\n<p>around the world</p>"
expect(diff(a, b)).to eq(
"<p>this #{del 'was'}#{ins 'is'}</p>"\
"\n<p> the " \
"#{del 'original'}#{ins 'new'}" \
" string</p>\n" \
"<p>#{ins 'around the world'}</p>"
)
end
end
context "text format" do
let(:opts) { { diff_format: :text } }
it "removes html" do
expect(p_diff).to eq("#{del 'old'}#{ins 'new'}")
end
it "compares complete links" do
diff = described_class.complete("[[A]]\n[[B]]", "[[A]]\n[[C]]",
diff_format: :html)
expect(diff).to eq("[[A]]\n#{del '[[B]]'}#{ins '[[C]]'}")
end
it "compares complete nests" do
diff = described_class.complete("{{A}}\n{{B}}", "{{A}}\n{{C}}",
diff_format: :html)
expect(diff).to eq("{{A}}\n#{del '{{B}}'}#{ins '{{C}}'}")
end
end
context "raw format" do
let(:opts) { { diff_format: :raw } }
it "excapes html" do
expect(p_diff).to eq("#{tag 'p'}#{del 'old'}#{ins 'new'}#{tag '/p'}")
end
it "diff for tag change" do
expect(diff(old_p, new_h))
.to eq(del("#{tag 'p'}old#{tag '/p'}") + ins("#{tag 'h1'}new#{tag '/h1'}"))
end
end
context "pointer format" do
let(:opts) { { diff_format: :pointer } }
it "removes square brackets" do
expect(diff("[[Hello]]", "[[Hi]]")).to eq(del("Hello<br>") + ins("Hi<br>"))
end
end
end