# encoding: utf-8

require File.join(File.expand_path(File.dirname(__FILE__)), "spec_helper")

describe "Text::Formatted::Box wrapping" do
  before(:each) do
    create_pdf
  end

  it "should not wrap between two fragments" do
    texts = [
      { :text => "Hello " },
      { :text => "World" },
      { :text => "2", :styles => [:superscript] }
    ]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
    text_box.render
    expect(text_box.text).to eq("Hello\nWorld2")
  end

  it "should not raise an Encoding::CompatibilityError when keeping a TTF and an AFM font together" do
    file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"

    @pdf.font_families["Kai"] = {
      :normal => { :file => file, :font => "Kai" }
    }

    texts = [
      { :text => "Hello " },
      { :text => "再见", :font => "Kai" },
      { :text => "World" }
    ]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))

    text_box.render
  end

  it "should wrap between two fragments when the preceding fragment ends with white space" do
    texts = [
      { :text => "Hello " },
      { :text => "World " },
      { :text => "2", :styles => [:superscript] }
    ]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
    text_box.render
    expect(text_box.text).to eq("Hello World\n2")

    texts = [
      { :text => "Hello " },
      { :text => "World\n" },
      { :text => "2", :styles => [:superscript] }
    ]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
    text_box.render
    expect(text_box.text).to eq("Hello World\n2")
  end

  it "should wrap between two fragments when the final fragment begins with white space" do
    texts = [
      { :text => "Hello " },
      { :text => "World" },
      { :text => " 2", :styles => [:superscript] }
    ]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
    text_box.render
    expect(text_box.text).to eq("Hello World\n2")

    texts = [
      { :text => "Hello " },
      { :text => "World" },
      { :text => "\n2", :styles => [:superscript] }
    ]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Hello World"))
    text_box.render
    expect(text_box.text).to eq("Hello World\n2")
  end

  it "should properly handle empty slices using default encoding" do
    texts = [{ :text => "Noua Delineatio Geographica generalis | Apostolicarum peregrinationum | S FRANCISCI XAUERII | Indiarum & Iaponiæ Apostoli", :font => 'Courier', :size => 10 }]
    text_box = Prawn::Text::Formatted::Box.new(texts, :document => @pdf, :width => @pdf.width_of("Noua Delineatio Geographica gen"))
    expect {
      text_box.render
    }.not_to raise_error
    expect(text_box.text).to eq("Noua Delineatio Geographica\ngeneralis | Apostolicarum\nperegrinationum | S FRANCISCI\nXAUERII | Indiarum & Iaponi\346\nApostoli")
  end
end

describe "Text::Formatted::Box with :fallback_fonts option that includes" \
  "a Chinese font and set of Chinese glyphs not in the current font" do
  it "should change the font to the Chinese font for the Chinese glyphs" do
    create_pdf
    file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
    @pdf.font_families["Kai"] = {
      :normal => { :file => file, :font => "Kai" }
    }
    formatted_text = [{ :text => "hello你好" },
                      { :text => "再见goodbye" }]
    @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])

    text = PDF::Inspector::Text.analyze(@pdf.render)

    fonts_used = text.font_settings.map { |e| e[:name] }
    expect(fonts_used.length).to eq(4)
    expect(fonts_used[0]).to eq(:Helvetica)
    expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[3]).to eq(:Helvetica)

    expect(text.strings[0]).to eq("hello")
    expect(text.strings[1]).to eq("你好")
    expect(text.strings[2]).to eq("再见")
    expect(text.strings[3]).to eq("goodbye")
  end
end

describe "Text::Formatted::Box with :fallback_fonts option that includes" \
  "an AFM font and Win-Ansi glyph not in the current Chinese font" do
  it "should change the font to the AFM font for the Win-Ansi glyph" do
    create_pdf
    file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
    @pdf.font_families["Kai"] = {
      :normal => { :file => file, :font => "Kai" }
    }
    @pdf.font("Kai")
    formatted_text = [{ :text => "hello你好" },
                      { :text => "再见€" }]
    @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Helvetica"])

    text = PDF::Inspector::Text.analyze(@pdf.render)

    fonts_used = text.font_settings.map { |e| e[:name] }
    expect(fonts_used.length).to eq(4)
    expect(fonts_used[0].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[3]).to eq(:Helvetica)

    expect(text.strings[0]).to eq("hello")
    expect(text.strings[1]).to eq("你好")
    expect(text.strings[2]).to eq("再见")
    expect(text.strings[3]).to eq("€")
  end
end

describe "Text::Formatted::Box with :fallback_fonts option and fragment " \
  "level font" do
  it "should use the fragment level font except for glyphs not in that font" do
    create_pdf
    file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
    @pdf.font_families["Kai"] = {
      :normal => { :file => file, :font => "Kai" }
    }

    file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
    @pdf.font_families["DejaVu Sans"] = {
      :normal => { :file => file }
    }

    formatted_text = [{ :text => "hello你好" },
                      { :text => "再见goodbye", :font => "Times-Roman" }]
    @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Kai"])

    text = PDF::Inspector::Text.analyze(@pdf.render)

    fonts_used = text.font_settings.map { |e| e[:name] }
    expect(fonts_used.length).to eq(4)
    expect(fonts_used[0]).to eq(:Helvetica)
    expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[2].to_s).to match(/GBZenKai-Medium/)
    expect(fonts_used[3]).to eq(:"Times-Roman")

    expect(text.strings[0]).to eq("hello")
    expect(text.strings[1]).to eq("你好")
    expect(text.strings[2]).to eq("再见")
    expect(text.strings[3]).to eq("goodbye")
  end
end

describe "Text::Formatted::Box" do
  before(:each) do
    create_pdf
    file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
    @pdf.font_families["Kai"] = {
      :normal => { :file => file, :font => "Kai" }
    }

    file = "#{Prawn::DATADIR}/fonts/DejaVuSans.ttf"
    @pdf.font_families["DejaVu Sans"] = {
      :normal => { :file => file }
    }

    @formatted_text = [{ :text => "hello你好" }]
    @pdf.fallback_fonts(["Kai"])
    @pdf.fallback_fonts = ["Kai"]
  end
  it "#fallback_fonts should return the document-wide fallback fonts" do
    expect(@pdf.fallback_fonts).to eq(["Kai"])
  end
  it "should be able to set text fallback_fonts document-wide" do
    @pdf.formatted_text_box(@formatted_text)

    text = PDF::Inspector::Text.analyze(@pdf.render)

    fonts_used = text.font_settings.map { |e| e[:name] }
    expect(fonts_used.length).to eq(2)
    expect(fonts_used[0]).to eq(:Helvetica)
    expect(fonts_used[1].to_s).to match(/GBZenKai-Medium/)
  end
  it "should be able to override document-wide fallback_fonts" do
    @pdf.fallback_fonts = ["DejaVu Sans"]
    @pdf.formatted_text_box(@formatted_text, :fallback_fonts => ["Kai"])

    text = PDF::Inspector::Text.analyze(@pdf.render)

    fonts_used = text.font_settings.map { |e| e[:name] }
    expect(fonts_used.length).to eq(2)
    expect(fonts_used[0]).to eq(:Helvetica)
    expect(fonts_used[1]).to match(/Kai/)
  end
  it "should omit the fallback fonts overhead when passing an empty array " \
    "as the :fallback_fonts" do
    @pdf.font("Kai")

    box = Prawn::Text::Formatted::Box.new(@formatted_text,
                                          :document => @pdf,
                                          :fallback_fonts => [])

    expect(box).to_not receive(:process_fallback_fonts)
    box.render
  end

  it "should be able to clear document-wide fallback_fonts" do
    @pdf.fallback_fonts([])
    box = Prawn::Text::Formatted::Box.new(@formatted_text,
                                          :document => @pdf)

    @pdf.font("Kai")

    expect(box).to_not receive(:process_fallback_fonts)
    box.render
  end
end

describe "Text::Formatted::Box with :fallback_fonts option " \
  "with glyphs not in the primary or the fallback fonts" do
  it "should raise an exception" do
    file = "#{Prawn::DATADIR}/fonts/gkai00mp.ttf"
    create_pdf
    formatted_text = [{ :text => "hello world. 世界你好。" }]

    expect {
      @pdf.formatted_text_box(formatted_text, :fallback_fonts => ["Courier"])
    }.to raise_error(Prawn::Errors::IncompatibleStringEncoding)
  end
end

describe "Text::Formatted::Box#extensions" do
  it "should be able to override default line wrapping" do
    create_pdf
    Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
    @pdf.formatted_text_box([{ :text => "hello world" }], {})
    Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
    text = PDF::Inspector::Text.analyze(@pdf.render)
    expect(text.strings[0]).to eq("all your base are belong to us")
  end
  it "overriding Text::Formatted::Box line wrapping should not affect " \
     "Text::Box wrapping" do
    create_pdf
    Prawn::Text::Formatted::Box.extensions << TestFormattedWrapOverride
    @pdf.text_box("hello world", {})
    Prawn::Text::Formatted::Box.extensions.delete(TestFormattedWrapOverride)
    text = PDF::Inspector::Text.analyze(@pdf.render)
    expect(text.strings[0]).to eq("hello world")
  end
  it "overriding Text::Box line wrapping should override Text::Box wrapping" do
    create_pdf
    Prawn::Text::Box.extensions << TestFormattedWrapOverride
    @pdf.text_box("hello world", {})
    Prawn::Text::Box.extensions.delete(TestFormattedWrapOverride)
    text = PDF::Inspector::Text.analyze(@pdf.render)
    expect(text.strings[0]).to eq("all your base are belong to us")
  end
end

describe "Text::Formatted::Box#render" do
  it "should handle newlines" do
    create_pdf
    array = [{ :text => "hello\nworld" }]
    options = { :document => @pdf }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    expect(text_box.text).to eq("hello\nworld")
  end
  it "should omit spaces from the beginning of the line" do
    create_pdf
    array = [{ :text => " hello\n world" }]
    options = { :document => @pdf }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    expect(text_box.text).to eq("hello\nworld")
  end
  it "should be okay printing a line of whitespace" do
    create_pdf
    array = [{ :text => "hello\n    \nworld" }]
    options = { :document => @pdf }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    expect(text_box.text).to eq("hello\n\nworld")

    array = [{ :text => "hello" + " " * 500 },
             { :text => " " * 500 },
             { :text => " " * 500 + "\n" },
             { :text => "world" }]
    options = { :document => @pdf }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    expect(text_box.text).to eq("hello\n\nworld")
  end
  it "should enable fragment level direction setting" do
    create_pdf
    number_of_hellos = 18
    array = [
      { :text => "hello " * number_of_hellos },
      { :text => "world", :direction => :ltr },
      { :text => ", how are you?" }
    ]
    options = { :document => @pdf, :direction => :rtl }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    text = PDF::Inspector::Text.analyze(@pdf.render)
    expect(text.strings[0]).to eq("era woh ,")
    expect(text.strings[1]).to eq("world")
    expect(text.strings[2]).to eq(" olleh" * number_of_hellos)
    expect(text.strings[3]).to eq("?uoy")
  end
end

describe "Text::Formatted::Box#render" do
  it "should be able to perform fragment callbacks" do
    create_pdf
    callback_object = TestFragmentCallback.new("something", 7, :document => @pdf)
    expect(callback_object).to receive(:render_behind).with(
      kind_of(Prawn::Text::Formatted::Fragment)
    )
    expect(callback_object).to receive(:render_in_front).with(
      kind_of(Prawn::Text::Formatted::Fragment)
    )
    array = [{ :text => "hello world " },
             { :text => "callback now",
               :callback => callback_object }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
  end
  it "should be able to perform fragment callbacks on multiple objects" do
    create_pdf

    callback_object = TestFragmentCallback.new("something", 7, :document => @pdf)
    expect(callback_object).to receive(:render_behind).with(
      kind_of(Prawn::Text::Formatted::Fragment)
    )
    expect(callback_object).to receive(:render_in_front).with(
      kind_of(Prawn::Text::Formatted::Fragment)
    )

    callback_object2 = TestFragmentCallback.new("something else", 14, :document => @pdf)
    expect(callback_object2).to receive(:render_behind).with(
      kind_of(Prawn::Text::Formatted::Fragment)
    )
    expect(callback_object2).to receive(:render_in_front).with(
      kind_of(Prawn::Text::Formatted::Fragment)
    )

    array = [{ :text => "hello world " },
             { :text => "callback now",
               :callback => [callback_object, callback_object2] }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
  end
  it "fragment callbacks should be able to define only the callback they need" do
    create_pdf
    behind = TestFragmentCallbackBehind.new("something", 7,
                                            :document => @pdf)
    in_front = TestFragmentCallbackInFront.new("something", 7,
                                               :document => @pdf)
    array = [{ :text => "hello world " },
             { :text => "callback now",
               :callback => [behind, in_front] }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)

    text_box.render # trigger callbacks
  end
  it "should be able to set the font" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "Times-Bold",
               :styles => [:bold],
               :font => "Times-Roman" },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    fonts = contents.font_settings.map { |e| e[:name] }
    expect(fonts).to eq([:Helvetica, :"Times-Bold", :Helvetica])
    expect(contents.strings[0]).to eq("this contains ")
    expect(contents.strings[1]).to eq("Times-Bold")
    expect(contents.strings[2]).to eq(" text")
  end
  it "should be able to set bold" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "bold", :styles => [:bold] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    fonts = contents.font_settings.map { |e| e[:name] }
    expect(fonts).to eq([:Helvetica, :"Helvetica-Bold", :Helvetica])
    expect(contents.strings[0]).to eq("this contains ")
    expect(contents.strings[1]).to eq("bold")
    expect(contents.strings[2]).to eq(" text")
  end
  it "should be able to set italics" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "italic", :styles => [:italic] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    fonts = contents.font_settings.map { |e| e[:name] }
    expect(fonts).to eq([:Helvetica, :"Helvetica-Oblique", :Helvetica])
  end
  it "should be able to set subscript" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "subscript", :size => 18, :styles => [:subscript] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    expect(contents.font_settings[0][:size]).to eq(12)
    expect(contents.font_settings[1][:size]).to be_within(0.0001).of(18 * 0.583)
  end
  it "should be able to set superscript" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "superscript", :size => 18, :styles => [:superscript] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    expect(contents.font_settings[0][:size]).to eq(12)
    expect(contents.font_settings[1][:size]).to be_within(0.0001).of(18 * 0.583)
  end
  it "should be able to set compound bold and italic text" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "bold italic", :styles => [:bold, :italic] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    fonts = contents.font_settings.map { |e| e[:name] }
    expect(fonts).to eq([:Helvetica, :"Helvetica-BoldOblique", :Helvetica])
  end
  it "should be able to underline" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "underlined", :styles => [:underline] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
    expect(line_drawing.points.length).to eq(2)
  end
  it "should be able to strikethrough" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "struckthrough", :styles => [:strikethrough] },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    line_drawing = PDF::Inspector::Graphics::Line.analyze(@pdf.render)
    expect(line_drawing.points.length).to eq(2)
  end
  it "should be able to add URL links" do
    create_pdf
    expect(@pdf).to receive(:link_annotation).with(kind_of(Array), :Border => [0, 0, 0],
                                                                   :A => {
                                                                     :Type => :Action,
                                                                     :S => :URI,
                                                                     :URI => "http://example.com"
                                                                   })
    array = [{ :text => "click " },
             { :text => "here", :link => "http://example.com" },
             { :text => " to visit" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
  end
  it "should be able to add destination links" do
    create_pdf
    expect(@pdf).to receive(:link_annotation).with(kind_of(Array), :Border => [0, 0, 0],
                                                                   :Dest => "ToC")
    array = [{ :text => "Go to the " },
             { :text => "Table of Contents", :anchor => "ToC" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
  end
  it "should be able to add local actions" do
    create_pdf
    expect(@pdf).to receive(:link_annotation).with(kind_of(Array), :Border => [0, 0, 0],
                                                                   :A => {
                                                                     :Type => :Action,
                                                                     :S => :Launch,
                                                                     :F => "../example.pdf",
                                                                     :NewWindow => true
                                                                   })
    array = [{ :text => "click " },
             { :text => "here", :local => "../example.pdf" },
             { :text => " to open a local file" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
  end
  it "should be able to set font size" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "sized", :size => 24 },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    expect(contents.font_settings[0][:size]).to eq(12)
    expect(contents.font_settings[1][:size]).to eq(24)
  end
  it "should set the baseline based on the tallest fragment on a given line" do
    create_pdf
    array = [{ :text => "this contains " },
             { :text => "sized", :size => 24 },
             { :text => " text" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    @pdf.font_size(24) do
      expect(text_box.height).to be_within(0.001).of(@pdf.font.ascender + @pdf.font.descender)
    end
  end
  it "should be able to set color via an rgb hex string" do
    create_pdf
    array = [{ :text => "rgb",
               :color => "ff0000" }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
    expect(colors.fill_color_count).to eq(2)
    expect(colors.stroke_color_count).to eq(2)
  end
  it "should be able to set color using a cmyk array" do
    create_pdf
    array = [{ :text => "cmyk",
               :color => [100, 0, 0, 0] }]
    text_box = Prawn::Text::Formatted::Box.new(array, :document => @pdf)
    text_box.render
    colors = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
    expect(colors.fill_color_count).to eq(2)
    expect(colors.stroke_color_count).to eq(2)
  end
end

describe "Text::Formatted::Box#render(:dry_run => true)" do
  it "should not change the graphics state of the document" do
    create_pdf

    state_before = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
    fill_color_count = state_before.fill_color_count
    stroke_color_count = state_before.stroke_color_count
    stroke_color_space_count = state_before.stroke_color_space_count

    array = [{ :text => 'Foo',
               :color => [0, 0, 0, 100] }]
    options = { :document => @pdf }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render(:dry_run => true)

    state_after = PDF::Inspector::Graphics::Color.analyze(@pdf.render)
    expect(state_after.fill_color_count).to eq(fill_color_count)
    expect(state_after.stroke_color_count).to eq(stroke_color_count)
    expect(state_after.stroke_color_space_count).to eq(stroke_color_space_count)
  end
end

describe "Text::Formatted::Box#render with fragment level :character_spacing option" do
  it "should draw the character spacing to the document" do
    create_pdf
    array = [{ :text => "hello world",
               :character_spacing => 7 }]
    options = { :document => @pdf }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    expect(contents.character_spacing[0]).to eq(7)
  end
  it "should draw the character spacing to the document" do
    create_pdf
    array = [{ :text => "hello world",
               :font => "Courier",
               :character_spacing => 10 }]
    options = { :document => @pdf,
                :width => 100,
                :overflow => :expand }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    expect(text_box.text).to eq("hello\nworld")
  end
end

describe "Text::Formatted::Box#render with :align => :justify" do
  it "should not justify the last line of a paragraph" do
    create_pdf
    array = [{ :text => "hello world " },
             { :text => "\n" },
             { :text => "goodbye" }]
    options = { :document => @pdf, :align => :justify }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    contents = PDF::Inspector::Text.analyze(@pdf.render)
    expect(contents.word_spacing).to be_empty
  end
end

describe "Text::Formatted::Box#render with :valign => :center" do
  it "should have a bottom gap equal to baseline and bottom of box" do
    create_pdf
    box_height = 100
    y = 450
    array = [{ :text => 'Vertical Align' }]
    options = {
      :document => @pdf,
      :valign => :center,
      :at => [0, y],
      :width => 100,
      :height => box_height,
      :size => 16
    }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    line_padding = (box_height - text_box.height + text_box.descender) * 0.5
    baseline = y - line_padding

    expect(text_box.at[1]).to be_within(0.01).of(baseline)
  end
end

describe "Text::Formatted::Box#render with :valign => :bottom" do
  it "should not render a gap between the text and bottom of box" do
    create_pdf
    box_height = 100
    y = 450
    array = [{ :text => 'Vertical Align' }]
    options = {
      :document => @pdf,
      :valign => :bottom,
      :at => [0, y],
      :width => 100,
      :height => box_height,
      :size => 16
    }
    text_box = Prawn::Text::Formatted::Box.new(array, options)
    text_box.render
    top_padding = y - (box_height - text_box.height)

    expect(text_box.at[1]).to be_within(0.01).of(top_padding)
  end
end

class TestFragmentCallback
  def initialize(string, number, options)
    @document = options[:document]
  end

  def render_behind(fragment)
  end

  def render_in_front(fragment)
  end
end

class TestFragmentCallbackBehind
  def initialize(string, number, options)
    @document = options[:document]
  end

  def render_behind(fragment)
  end
end

class TestFragmentCallbackInFront
  def initialize(string, number, options)
    @document = options[:document]
  end

  def render_in_front(fragment)
  end
end

module TestFormattedWrapOverride
  def wrap(array)
    initialize_wrap([{ :text => 'all your base are belong to us' }])
    line_to_print = @line_wrap.wrap_line(:document => @document,
                                         :kerning => @kerning,
                                         :width => 10000,
                                         :arranger => @arranger)
    fragment = @arranger.retrieve_fragment
    format_and_draw_fragment(fragment, 0, @line_wrap.width, 0)

    []
  end
end
