Implement styles
All checks were successful
CI Pipeline / build (pull_request) Successful in 12s

This commit is contained in:
2025-12-02 12:02:51 +01:00
parent 1fffecf0eb
commit 58492e9ef6
16 changed files with 786 additions and 23 deletions

87
test/heading_test.rb Normal file
View File

@@ -0,0 +1,87 @@
# frozen_string_literal: true
require "test_helper"
class HeadingTest < Minitest::Test
include EzdocTestHelpers
def test_h1
xml = create_doc_and_read_xml { |doc| doc.h1 "Title" }
assert_includes xml, "<w:pStyle"
assert_includes xml, 'w:val="Heading1"'
assert_includes xml, "Title"
end
def test_h2
xml = create_doc_and_read_xml { |doc| doc.h2 "Chapter" }
assert_includes xml, 'w:val="Heading2"'
assert_includes xml, "Chapter"
end
def test_h3
xml = create_doc_and_read_xml { |doc| doc.h3 "Section" }
assert_includes xml, 'w:val="Heading3"'
end
def test_h4
xml = create_doc_and_read_xml { |doc| doc.h4 "Subsection" }
assert_includes xml, 'w:val="Heading4"'
end
def test_h5
xml = create_doc_and_read_xml { |doc| doc.h5 "Minor" }
assert_includes xml, 'w:val="Heading5"'
end
def test_h6
xml = create_doc_and_read_xml { |doc| doc.h6 "Smallest" }
assert_includes xml, 'w:val="Heading6"'
end
def test_heading_with_block
xml = create_doc_and_read_xml do |doc|
doc.h1 do
doc.text "Part 1 "
doc.b { doc.text "Bold" }
end
end
assert_includes xml, 'w:val="Heading1"'
assert_includes xml, "Part 1 "
assert_includes xml, "<w:b/>"
assert_includes xml, "Bold"
end
def test_multiple_headings
xml = create_doc_and_read_xml do |doc|
doc.h1 "Title"
doc.h2 "Chapter 1"
doc.h3 "Section 1.1"
doc.p "Normal paragraph"
end
assert_includes xml, 'w:val="Heading1"'
assert_includes xml, 'w:val="Heading2"'
assert_includes xml, 'w:val="Heading3"'
# Regular paragraph should not have pStyle
assert_equal 3, xml.scan("<w:pStyle").count
end
def test_heading_styles_in_styles_xml
xml_files = create_doc_and_read_all_xml do |doc|
doc.h1 "Test"
end
styles_xml = xml_files["word/styles.xml"]
assert styles_xml, "styles.xml should exist"
assert_includes styles_xml, 'w:styleId="Heading1"'
assert_includes styles_xml, "<w:b/>"
assert_includes styles_xml, "<w:sz"
end
end

171
test/style_test.rb Normal file
View File

@@ -0,0 +1,171 @@
# frozen_string_literal: true
require "test_helper"
class StyleTest < Minitest::Test
include EzdocTestHelpers
def test_define_custom_style
xml_files = create_doc_and_read_all_xml do |doc|
doc.define_style :warning, bold: true, color: "FF0000"
doc.p "Test", style: :warning
end
styles_xml = xml_files["word/styles.xml"]
assert_includes styles_xml, 'w:styleId="Warning"'
assert_includes styles_xml, "<w:b/>"
assert_includes styles_xml, 'w:val="FF0000"'
end
def test_apply_style_to_paragraph
xml = create_doc_and_read_xml do |doc|
doc.p "Quote text", style: :quote
end
assert_includes xml, '<w:pStyle w:val="Quote"'
assert_includes xml, "Quote text"
end
def test_apply_style_to_text_run
xml = create_doc_and_read_xml do |doc|
doc.p do
doc.text "Normal "
doc.text "code", style: :code
end
end
assert_includes xml, '<w:rStyle w:val="Code"'
assert_includes xml, "code"
end
def test_built_in_styles_exist
xml_files = create_doc_and_read_all_xml do |doc|
doc.p "Test"
end
styles_xml = xml_files["word/styles.xml"]
assert_includes styles_xml, 'w:styleId="Heading1"'
assert_includes styles_xml, 'w:styleId="Heading2"'
assert_includes styles_xml, 'w:styleId="Title"'
assert_includes styles_xml, 'w:styleId="Subtitle"'
assert_includes styles_xml, 'w:styleId="Quote"'
assert_includes styles_xml, 'w:styleId="Code"'
end
def test_style_with_color
xml_files = create_doc_and_read_all_xml do |doc|
doc.define_style :red_text, color: "FF0000"
doc.p "Red", style: :red_text
end
styles_xml = xml_files["word/styles.xml"]
assert_includes styles_xml, 'w:val="FF0000"'
end
def test_style_with_font
xml_files = create_doc_and_read_all_xml do |doc|
doc.define_style :mono, font: "Courier New"
doc.p "Mono", style: :mono
end
styles_xml = xml_files["word/styles.xml"]
assert_includes styles_xml, 'w:ascii="Courier New"'
end
def test_style_with_size
xml_files = create_doc_and_read_all_xml do |doc|
doc.define_style :big, size: 24
doc.p "Big", style: :big
end
styles_xml = xml_files["word/styles.xml"]
# 24pt = 48 half-points
assert_includes styles_xml, 'w:val="48"'
end
def test_style_with_alignment
xml_files = create_doc_and_read_all_xml do |doc|
doc.define_style :centered, align: :center
doc.p "Centered", style: :centered
end
styles_xml = xml_files["word/styles.xml"]
assert_includes styles_xml, '<w:jc w:val="center"'
end
def test_styles_xml_generated
xml_files = create_doc_and_read_all_xml do |doc|
doc.p "Test"
end
assert xml_files["word/styles.xml"], "styles.xml should be generated"
end
def test_styles_xml_in_content_types
xml_files = create_doc_and_read_all_xml do |doc|
doc.p "Test"
end
content_types = xml_files["[Content_Types].xml"]
assert_includes content_types, "/word/styles.xml"
assert_includes content_types, "wordprocessingml.styles+xml"
end
def test_styles_xml_in_relationships
xml_files = create_doc_and_read_all_xml do |doc|
doc.p "Test"
end
rels = xml_files["word/_rels/document.xml.rels"]
assert_includes rels, "styles.xml"
assert_includes rels, "relationships/styles"
end
def test_unknown_style_raises_error
assert_raises(ArgumentError) do
Tempfile.create(["test", ".docx"]) do |file|
Ezdoc::Document.create(file.path) do |doc|
doc.p "Test", style: :nonexistent
end
end
end
end
def test_invalid_color_raises_error
assert_raises(ArgumentError) do
Ezdoc::Style.new(:bad, color: "invalid")
end
end
def test_invalid_alignment_raises_error
assert_raises(ArgumentError) do
Ezdoc::Style.new(:bad, align: :invalid)
end
end
def test_color_normalizes_hash
style = Ezdoc::Style.new(:test, color: "#ff0000")
assert_equal "FF0000", style.color
end
def test_combined_style_properties
xml_files = create_doc_and_read_all_xml do |doc|
doc.define_style :fancy,
bold: true,
italic: true,
color: "0000FF",
size: 16,
font: "Arial",
align: :center
doc.p "Fancy", style: :fancy
end
styles_xml = xml_files["word/styles.xml"]
assert_includes styles_xml, "<w:b/>"
assert_includes styles_xml, "<w:i/>"
assert_includes styles_xml, 'w:val="0000FF"'
assert_includes styles_xml, 'w:val="32"' # 16pt = 32 half-points
assert_includes styles_xml, 'w:ascii="Arial"'
assert_includes styles_xml, '<w:jc w:val="center"'
end
end