mirror of
https://github.com/unidoc/unioffice.git
synced 2025-04-25 13:48:53 +08:00

* add ability to handle footnotes and endnotes * address review comments to make code much cleaner * add license headers and simple example
320 lines
7.1 KiB
Go
320 lines
7.1 KiB
Go
// Copyright 2017 FoxyUtils ehf. All rights reserved.
|
|
//
|
|
// Use of this source code is governed by the terms of the Affero GNU General
|
|
// Public License version 3.0 as published by the Free Software Foundation and
|
|
// appearing in the file LICENSE included in the packaging of this file. A
|
|
// commercial license can be purchased by contacting sales@baliance.com.
|
|
|
|
package document_test
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/unidoc/unioffice/document"
|
|
)
|
|
|
|
func TestFootnotesLoad(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestHasFootnotes(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
if !doc.HasFootnotes() {
|
|
t.Error("document should contain footnotes")
|
|
}
|
|
doc = document.New()
|
|
if doc.HasFootnotes() {
|
|
t.Error("document should not contain footnotes")
|
|
}
|
|
}
|
|
|
|
func TestFootnotesListFootnotes(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
if len(doc.Footnotes()) == 0 {
|
|
t.Error("document should contain footnotes")
|
|
}
|
|
if len(doc.Footnotes()) <= 2 {
|
|
t.Error("document should contain footnotes array that includes 2 added by the system")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesPullByID(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fn := doc.Footnote(2)
|
|
if fn.X().IdAttr != 2 {
|
|
t.Error("test did not retrieve the proper footnote")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesPullParagraphs(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fn := doc.Footnote(2)
|
|
if len(fn.Paragraphs()) == 0 {
|
|
t.Error("test did not retrieve the paragraphs properly")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesLinkedToRuns(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
var linkedRuns int = 0
|
|
for _, p := range doc.Paragraphs() {
|
|
for _, r := range p.Runs() {
|
|
if ok, _ := r.IsFootnote(); ok {
|
|
linkedRuns++
|
|
}
|
|
}
|
|
}
|
|
if linkedRuns == 0 {
|
|
t.Error("document not properly linked to footnotes")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesLinkedToRunsProperly(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
linkedFns := make([]document.Footnote, 0)
|
|
for _, p := range doc.Paragraphs() {
|
|
for _, r := range p.Runs() {
|
|
if ok, fnID := r.IsFootnote(); ok {
|
|
linkedFns = append(linkedFns, doc.Footnote(fnID))
|
|
}
|
|
}
|
|
}
|
|
if len(linkedFns) == 0 {
|
|
t.Error("document not properly linked to footnotes")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesHaveText(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fn := doc.Footnote(2)
|
|
var buff bytes.Buffer
|
|
for _, p1 := range fn.Paragraphs() {
|
|
for _, r2 := range p1.Runs() {
|
|
buff.WriteString(r2.Text())
|
|
}
|
|
}
|
|
if buff.String() == "" {
|
|
t.Error("content not accessible from footnote")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesClearContent(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fn := doc.Footnote(2)
|
|
var buff bytes.Buffer
|
|
for _, p1 := range fn.Paragraphs() {
|
|
for _, r2 := range p1.Runs() {
|
|
r2.Clear()
|
|
buff.WriteString(r2.Text())
|
|
}
|
|
}
|
|
output := buff.String()
|
|
if output != "" {
|
|
t.Errorf("content not cleared from footnote: %s", output)
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesSimplifyContent(t *testing.T) {
|
|
newTxt := "This will be shortened."
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
|
|
fn := doc.Footnote(2)
|
|
for i, p := range fn.Paragraphs() {
|
|
if i > 0 {
|
|
fn.RemoveParagraph(p)
|
|
}
|
|
for j, r := range p.Runs() {
|
|
if j > 0 {
|
|
p.RemoveRun(r)
|
|
}
|
|
r.Clear()
|
|
r.AddText(newTxt)
|
|
}
|
|
}
|
|
|
|
fn2 := doc.Footnote(2)
|
|
if len(fn2.Paragraphs()) != 1 {
|
|
t.Error("wrong number of paragraphs")
|
|
}
|
|
if len(fn2.Paragraphs()[0].Runs()) != 1 {
|
|
t.Errorf("wrong number of runs: expect %d, got %d", 1, len(fn2.Paragraphs()[0].Runs()))
|
|
}
|
|
if fn2.Paragraphs()[0].Runs()[0].Text() != newTxt {
|
|
t.Error("incorrect modification to footnote text")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesExpandContent(t *testing.T) {
|
|
newTxt := "This will be expanded."
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fn := doc.Footnote(3)
|
|
|
|
para := fn.AddParagraph()
|
|
run := para.AddRun()
|
|
run.AddText(newTxt)
|
|
|
|
fn2 := doc.Footnote(3)
|
|
if len(fn2.Paragraphs()) != 2 {
|
|
t.Error("wrong number of paragraphs")
|
|
}
|
|
if len(fn2.Paragraphs()[1].Runs()) != 1 {
|
|
t.Errorf("wrong number of runs: expect %d, got %d", 1, len(fn2.Paragraphs()[0].Runs()))
|
|
}
|
|
if fn2.Paragraphs()[1].Runs()[0].Text() != newTxt {
|
|
t.Error("incorrect modification to footnote text")
|
|
}
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesAddFootnote(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fnB4 := len(doc.Footnotes())
|
|
var fnB4InP int
|
|
var p document.Paragraph
|
|
for _, p1 := range doc.Paragraphs() {
|
|
for _, r := range p1.Runs() {
|
|
if ok, fnID := r.IsFootnote(); ok {
|
|
if fnID == 2 {
|
|
p = p1
|
|
fnB4InP++
|
|
}
|
|
}
|
|
}
|
|
}
|
|
fn := p.AddFootnote("testing")
|
|
|
|
if len(doc.Footnotes()) == fnB4 {
|
|
t.Fatal("did not properly add footnote")
|
|
}
|
|
|
|
var fnInP int
|
|
for _, r := range p.Runs() {
|
|
if ok, _ := r.IsFootnote(); ok {
|
|
fnInP++
|
|
}
|
|
}
|
|
|
|
if fnInP <= fnB4InP {
|
|
t.Error("footnotes not properly added to run")
|
|
}
|
|
|
|
pinner := fn.AddParagraph()
|
|
rinner := pinner.AddRun()
|
|
rinner.AddText("more test goes in this paragraph")
|
|
|
|
if len(fn.Paragraphs()) != 2 {
|
|
t.Error("wrong number of paragraphs in footnote")
|
|
}
|
|
for _, p := range fn.Paragraphs() {
|
|
if p.Properties().Style() != "Footnote" {
|
|
t.Error("wrong style set for the paragraph")
|
|
}
|
|
}
|
|
|
|
saveTestData(t, doc)
|
|
}
|
|
|
|
func TestFootnotesRemoveFootnote(t *testing.T) {
|
|
doc := loadTestData(t)
|
|
if doc == nil {
|
|
t.Fatal("could not read test document")
|
|
}
|
|
fnB4 := len(doc.Footnotes())
|
|
var runsInP int
|
|
var p document.Paragraph
|
|
for _, p1 := range doc.Paragraphs() {
|
|
for _, r := range p1.Runs() {
|
|
if ok, fnID := r.IsFootnote(); ok {
|
|
if fnID == 2 {
|
|
p = p1
|
|
runsInP = len(p.Runs())
|
|
}
|
|
}
|
|
}
|
|
}
|
|
p.RemoveFootnote(2)
|
|
|
|
if len(doc.Footnotes()) == fnB4 {
|
|
fmt.Println(doc.Footnotes())
|
|
t.Fatal("did not properly remove footnote")
|
|
}
|
|
|
|
if len(p.Runs()) >= runsInP {
|
|
t.Fatal("did not properly remove footnote")
|
|
}
|
|
}
|
|
|
|
func loadTestData(t *testing.T) *document.Document {
|
|
docBytes, err := ioutil.ReadFile(filepath.Join("testdata", "footnotes_endnotes.docx"))
|
|
if err != nil {
|
|
t.Error("cannot read text fixture from disk")
|
|
return nil
|
|
}
|
|
doc, err := document.Read(bytes.NewReader(docBytes), int64(len(docBytes)))
|
|
if err != nil {
|
|
t.Error("cannot unmarshal test fixture into document struct")
|
|
return nil
|
|
}
|
|
return doc
|
|
}
|
|
|
|
func saveTestData(t *testing.T, doc *document.Document) {
|
|
// Ensure the document can render
|
|
var b bytes.Buffer
|
|
buff := bufio.NewWriter(&b)
|
|
err := doc.Save(buff)
|
|
if err != nil {
|
|
t.Error("failure rendering document to docx:", err)
|
|
}
|
|
}
|