Add support for images

This commit is contained in:
2025-12-02 11:43:25 +01:00
parent 15493da657
commit 980192253f
15 changed files with 481 additions and 6 deletions

204
test/image_test.rb Normal file
View File

@@ -0,0 +1,204 @@
# frozen_string_literal: true
require "test_helper"
class ImageTest < Minitest::Test
include EzdocTestHelpers
def setup
@png_path = File.expand_path("fixtures/test.png", __dir__)
@jpeg_path = File.expand_path("fixtures/test.jpg", __dir__)
end
def test_image_in_paragraph
xml = create_doc_and_read_xml do |doc|
doc.p do
doc.image @png_path
end
end
assert_includes xml, "<w:drawing>"
assert_includes xml, "<wp:inline"
assert_includes xml, "<pic:pic>"
assert_includes xml, 'r:embed="rId'
end
def test_image_in_table_cell
xml = create_doc_and_read_xml do |doc|
doc.table do
doc.tr do
doc.td do
doc.image @png_path
end
end
end
end
assert_includes xml, "<w:tc>"
assert_includes xml, "<w:drawing>"
end
def test_image_in_list_item
xml = create_doc_and_read_xml do |doc|
doc.ul do
doc.li do
doc.image @png_path
end
end
end
assert_includes xml, "<w:numPr>"
assert_includes xml, "<w:drawing>"
end
def test_image_with_explicit_dimensions_inches
xml = create_doc_and_read_xml do |doc|
doc.p do
doc.image @png_path, width: "2in", height: "1in"
end
end
# 2 inches = 1828800 EMUs
assert_includes xml, 'cx="1828800"'
# 1 inch = 914400 EMUs
assert_includes xml, 'cy="914400"'
end
def test_image_with_explicit_dimensions_cm
xml = create_doc_and_read_xml do |doc|
doc.p do
doc.image @png_path, width: "5cm", height: "3cm"
end
end
# 5 cm = 1800000 EMUs
assert_includes xml, 'cx="1800000"'
# 3 cm = 1080000 EMUs
assert_includes xml, 'cy="1080000"'
end
def test_image_file_embedded_in_docx
files = nil
Tempfile.create(["test", ".docx"]) do |file|
Ezdoc::Document.create(file.path) do |doc|
doc.p { doc.image @png_path }
end
Zip::File.open(file.path) do |zip|
files = zip.entries.map(&:name)
end
end
assert(files.any? { |f| f.start_with?("word/media/image") })
end
def test_image_relationships_generated
xml_files = create_doc_and_read_all_xml do |doc|
doc.p { doc.image @png_path }
end
rels = xml_files["word/_rels/document.xml.rels"]
assert_includes rels, "relationships/image"
assert_includes rels, "media/image"
end
def test_image_content_type_registered
xml_files = create_doc_and_read_all_xml do |doc|
doc.p { doc.image @png_path }
end
content_types = xml_files["[Content_Types].xml"]
assert_includes content_types, 'Extension="png"'
assert_includes content_types, "image/png"
end
def test_jpeg_content_type_registered
xml_files = create_doc_and_read_all_xml do |doc|
doc.p { doc.image @jpeg_path }
end
content_types = xml_files["[Content_Types].xml"]
assert_includes content_types, 'Extension="jpeg"'
assert_includes content_types, "image/jpeg"
end
def test_invalid_image_path_raises_error
assert_raises(ArgumentError) do
Tempfile.create(["test", ".docx"]) do |file|
Ezdoc::Document.create(file.path) do |doc|
doc.p { doc.image "/nonexistent/image.png" }
end
end
end
end
def test_unsupported_format_raises_error
Tempfile.create(["test", ".gif"]) do |gif_file|
gif_file.write("GIF89a")
gif_file.flush
assert_raises(ArgumentError) do
Tempfile.create(["test", ".docx"]) do |docx_file|
Ezdoc::Document.create(docx_file.path) do |doc|
doc.p { doc.image gif_file.path }
end
end
end
end
end
def test_same_image_used_multiple_times_deduplication
files = nil
Tempfile.create(["test", ".docx"]) do |file|
Ezdoc::Document.create(file.path) do |doc|
doc.p { doc.image @png_path }
doc.p { doc.image @png_path }
doc.p { doc.image @png_path }
end
Zip::File.open(file.path) do |zip|
files = zip.entries.map(&:name).select { |f| f.start_with?("word/media/") }
end
end
# Should only have one image file despite being used 3 times
assert_equal 1, files.size
end
def test_multiple_different_images
files = nil
Tempfile.create(["test", ".docx"]) do |file|
Ezdoc::Document.create(file.path) do |doc|
doc.p { doc.image @png_path }
doc.p { doc.image @jpeg_path }
end
Zip::File.open(file.path) do |zip|
files = zip.entries.map(&:name).select { |f| f.start_with?("word/media/") }
end
end
assert_equal 2, files.size
end
def test_image_with_text_in_same_paragraph
xml = create_doc_and_read_xml do |doc|
doc.p do
doc.text "Before image: "
doc.image @png_path
doc.text " After image"
end
end
assert_includes xml, "Before image: "
assert_includes xml, "After image"
assert_includes xml, "<w:drawing>"
end
def test_image_dimensions_read_from_file
xml = create_doc_and_read_xml do |doc|
doc.p { doc.image @png_path }
end
# 200x200 pixels at 96 DPI = 200 * (914400 / 96) = 1905000 EMUs
assert_includes xml, 'cx="1905000"'
assert_includes xml, 'cy="1905000"'
end
end