# frozen_string_literal: true require 'spec_helper' describe Prawn::Text::Formatted::Fragment do let(:pdf) { create_pdf } describe 'Text::Formatted::Fragment' do let(:fragment) do format_state = { styles: %i[bold italic], color: nil, link: nil, anchor: nil, font: nil, size: nil } described_class.new( 'hello world', format_state, pdf ).tap do |fragment| fragment.width = 100 fragment.left = 50 fragment.baseline = 200 fragment.line_height = 27 fragment.descender = 7 fragment.ascender = 17 end end describe '#width' do it 'returns the width' do expect(fragment.width).to eq(100) end end describe '#styles' do it 'returns the styles array' do expect(fragment.styles).to eq(%i[bold italic]) end it 'nevers return nil' do format_state = { styles: nil, color: nil, link: nil, anchor: nil, font: nil, size: nil } fragment = described_class.new( 'hello world', format_state, pdf ) expect(fragment.styles).to eq([]) end end describe '#line_height' do it 'returns the line_height' do expect(fragment.line_height).to eq(27) end end describe '#ascender' do it 'returns the ascender' do expect(fragment.ascender).to eq(17) end end describe '#descender' do it 'returns the descender' do expect(fragment.descender).to eq(7) end end describe '#y_offset' do it 'is zero' do expect(fragment.y_offset).to eq(0) end end describe '#bounding_box' do it 'returns the bounding box surrounding the fragment' do target_box = [50, 193, 150, 217] expect(fragment.bounding_box).to eq(target_box) end end describe '#absolute_bounding_box' do it 'returns the bounding box surrounding the fragment' \ ' in absolute coordinates' do target_box = [50, 193, 150, 217] target_box[0] += pdf.bounds.absolute_left target_box[1] += pdf.bounds.absolute_bottom target_box[2] += pdf.bounds.absolute_left target_box[3] += pdf.bounds.absolute_bottom expect(fragment.absolute_bounding_box).to eq(target_box) end end describe '#underline_points' do it 'defines a line under the fragment' do y = 198.75 target_points = [[50, y], [150, y]] expect(fragment.underline_points).to eq(target_points) end end describe '#strikethrough_points' do it 'defines a line through the fragment' do y = 200 + fragment.ascender * 0.3 target_points = [[50, y], [150, y]] expect(fragment.strikethrough_points).to eq(target_points) end end end describe '#space_count' do it 'returns the number of spaces in the fragment' do format_state = {} fragment = described_class.new( 'hello world ', format_state, pdf ) expect(fragment.space_count).to eq(2) end it 'excludes trailing spaces from the count when ' \ ':exclude_trailing_white_space => true' do format_state = { exclude_trailing_white_space: true } fragment = described_class.new( 'hello world ', format_state, pdf ) expect(fragment.space_count).to eq(1) end end describe '#include_trailing_white_space!' do it 'makes the fragment include trailing white space' do format_state = { exclude_trailing_white_space: true } fragment = described_class.new( 'hello world ', format_state, pdf ) expect(fragment.space_count).to eq(1) fragment.include_trailing_white_space! expect(fragment.space_count).to eq(2) end end describe '#text' do it 'returns the fragment text' do format_state = {} fragment = described_class.new( 'hello world ', format_state, pdf ) expect(fragment.text).to eq('hello world ') end it 'returns the fragment text without trailing spaces when ' \ ':exclude_trailing_white_space => true' do format_state = { exclude_trailing_white_space: true } fragment = described_class.new( 'hello world ', format_state, pdf ) expect(fragment.text).to eq('hello world') end end describe '#word_spacing=' do let(:fragment) do format_state = { styles: %i[bold italic], color: nil, link: nil, anchor: nil, font: nil, size: nil } described_class.new( 'hello world', format_state, pdf ).tap do |fragment| fragment.width = 100 fragment.left = 50 fragment.baseline = 200 fragment.line_height = 27 fragment.descender = 7 fragment.ascender = 17 fragment.word_spacing = 10 end end it 'accounts for word_spacing in #width' do expect(fragment.width).to eq(110) end it 'accounts for word_spacing in #bounding_box' do target_box = [50, 193, 160, 217] expect(fragment.bounding_box).to eq(target_box) end it 'accounts for word_spacing in #absolute_bounding_box' do target_box = [50, 193, 160, 217] target_box[0] += pdf.bounds.absolute_left target_box[1] += pdf.bounds.absolute_bottom target_box[2] += pdf.bounds.absolute_left target_box[3] += pdf.bounds.absolute_bottom expect(fragment.absolute_bounding_box).to eq(target_box) end it 'accounts for word_spacing in #underline_points' do y = 198.75 target_points = [[50, y], [160, y]] expect(fragment.underline_points).to eq(target_points) end it 'accounts for word_spacing in #strikethrough_points' do y = 200 + fragment.ascender * 0.3 target_points = [[50, y], [160, y]] expect(fragment.strikethrough_points).to eq(target_points) end end describe 'subscript' do let(:fragment) do format_state = { styles: [:subscript], color: nil, link: nil, anchor: nil, font: nil, size: nil } described_class.new( 'hello world', format_state, pdf ).tap do |fragment| fragment.line_height = 27 fragment.descender = 7 fragment.ascender = 17 end end describe '#subscript?' do it 'be_trues' do expect(fragment).to be_subscript end end describe '#y_offset' do it 'returns a negative value' do expect(fragment.y_offset).to be < 0 end end end describe 'superscript' do let(:fragment) do format_state = { styles: [:superscript], color: nil, link: nil, anchor: nil, font: nil, size: nil } described_class.new( 'hello world', format_state, pdf ).tap do |fragment| fragment.line_height = 27 fragment.descender = 7 fragment.ascender = 17 end end describe '#superscript?' do it 'be_trues' do expect(fragment).to be_superscript end end describe '#y_offset' do it 'returns a positive value' do expect(fragment.y_offset).to be > 0 end end end context 'with :direction => :rtl' do it '#text should be reversed' do format_state = { direction: :rtl } fragment = described_class.new( 'hello world', format_state, pdf ) expect(fragment.text).to eq('dlrow olleh') end end describe '#default_direction=' do it 'sets the direction if there is no fragment level direction ' \ 'specification' do format_state = {} fragment = described_class.new( 'hello world', format_state, pdf ) fragment.default_direction = :rtl expect(fragment.direction).to eq(:rtl) end it 'does not set the direction if there is a fragment level direction ' \ 'specification' do format_state = { direction: :rtl } fragment = described_class.new( 'hello world', format_state, pdf ) fragment.default_direction = :ltr expect(fragment.direction).to eq(:rtl) end end end